Wie funktioniert das verdinglichte Keyword in Kotlin?

11

Ich versuche den Sinn des reified Keywords zu verstehen, anscheinend es erlaubt uns, darüber nachzudenken Generika .

Aber wenn ich es weglasse, funktioniert es genauso gut. Will jemand erklären, wenn dies einen tatsächlichen Unterschied macht?

    
hl3mukkel 29.08.2017, 23:11
quelle

1 Antwort

36

TL; DR: Was ist reified gut für

In einer normalen generischen Funktion wie

%Vor%

Sie können nicht auf den Typ T zugreifen, da nur zur Kompilierzeit verfügbar ist , aber gelöscht zur Laufzeit. Wenn Sie also den generischen Typ als normale Klasse im Funktionskörper verwenden möchten, müssen Sie explizit die Klasse als Parameter übergeben , wie in myGenericFun gezeigt.

Wenn Sie eine inline -Funktion mit einem verdinglicht T erstellen, können Sie auch auf den Typ von T zugreifen, auch zur Laufzeit, so dass Sie Class<T> nicht übergeben müssen. zusätzlich. Sie können mit T so arbeiten, als wäre es eine normale Klasse, z. Vielleicht möchten Sie überprüfen, ob eine Variable eine Instanz von T ist, was Sie dann einfach tun können: myVar is T .

Eine solche Funktion inline mit reified type T sieht folgendermaßen aus:

%Vor%

Wie funktioniert reified

?

Sie können reified nur in Kombination mit einer Funktion inline verwenden. Eine solche Funktion bewirkt, dass der Compiler den Bytecode der Funktion an jede Stelle kopiert, an der die Funktion verwendet wird (die Funktion wird "inline"). Wenn Sie eine Inline-Funktion mit einem verdichteten Typ aufrufen, kennt der -Compiler den eigentlichen Typ, der als Typargument verwendet wird, und ändert den generierten Bytecode, um die entsprechende Klasse direkt zu verwenden. Daher werden Aufrufe wie myVar is T zu myVar is String (wenn das Typargument String war) im Bytecode und zur Laufzeit.

Beispiel

Sehen wir uns ein Beispiel an, das zeigt, wie hilfreich reified sein kann. Wir möchten eine Erweiterungsfunktion für String namens toKotlinObject erstellen, die versucht, eine JSON-Zeichenfolge in ein einfaches Kotlin-Objekt mit einem Typ zu konvertieren, der vom generischen Typ der Funktion T angegeben wird. Wir können com.fasterxml.jackson.module.kotlin dafür verwenden und der erste Ansatz ist folgender:

Erste Annäherung ohne verdichteten Typ

%Vor%

Die Methode readValue verwendet einen Typ, mit dem JsonObject analysiert werden soll. Wenn wir versuchen, die Class des Typparameters T zu erhalten, beschwert sich der Compiler: "Kann 'T' nicht als verdingter Typparameter verwenden. Stattdessen eine Klasse verwenden."

Umgehung mit explizitem Class -Parameter

%Vor%

Als Workaround kann der Class von T zu einem Methodenparameter gemacht werden, der dann als Argument für readValue verwendet wird. Dies funktioniert und ist ein allgemeines Muster im generischen Java-Code. Es kann wie folgt aufgerufen werden:

%Vor%

Der Kotlin-Weg: reified

Die Verwendung einer Funktion inline mit reified type Parameter T ermöglicht es, die Funktion anders zu implementieren:

%Vor%

Es ist nicht nötig, das Class von T zusätzlich zu verwenden, T kann verwendet werden, als wäre es eine gewöhnliche Klasse. Für den Client sieht der Code so aus:

%Vor%

Wichtiger Hinweis: Arbeiten mit Java

Eine Inline-Funktion mit reified type ist nicht aus Java -Code aufrufbar.

    
s1m0nw1 30.08.2017, 04:56
quelle