5

Angenommen, den folgenden Code:Wie Übergeben eines Typparameters an eine generische Klassenkonstruktorreferenz?

class ConstructMe<T> {} 
data class Test<T> constructor(var supplier:() -> ConstructMe<T>) {} 

fun main(args: Array<String>) { 
    works<Int>() 
    breaks<Int>() 
} 

fun <T> works() { 
    Test<T>({ ConstructMe<T>() }) // (1) any one class type parameter can be removed like: 
    Test({ ConstructMe<T>() }) // (2) still works (class type inferred by argument type) 
    Test<T>({ ConstructMe() }) // (3) still works (argument type inferred by class type) 
} 

fun <T> breaks() { 
    Test<T>(::ConstructMe) // type interference failed (should probably work like (3); compiler improvement possible?) 
    Test<T>(::ConstructMe<T>) // type interference failed & type argument not allowed (language change necessary?) 
} 

Ich habe in diesem Lauf durch Eigenschaften JavaFX vorbei (SimpleIntegerProperty, SimpleStringProperty, ... und SimpleObjectProperty<T>) auf eine generische Klasse Bauer () -> Property<T> Argument, wo ::SimpleIntegerProperty Arbeiten ohne Probleme vorbei , während ::SimpleObjectProperty wie der obige Beispielcode fehlschlägt.

Ist es möglich, den Compiler hier zu verbessern oder die Übergabe von Typparametern an Konstruktor-/Funktionsreferenzen zu erlauben? Macht es überhaupt Sinn, Konstruktorreferenzen gegenüber einfachen Lambda-Ausdrücken zu verwenden? Komponiert es anders?

Antwort

2

Ja, hier ist es möglich, den Compiler zu verbessern. Er könnte den Typparameter für ConstructMe ableiten. Siehe Ausgabe https://youtrack.jetbrains.com/issue/KT-10711.

Für Nicht-Inline-Counter-Funktion (in diesem Fall ist es Konstruktor von Test) gibt es keinen Unterschied zwischen Lambda und Callable Verweis auf Konstruktor. In beiden Fällen erstellt der Compiler eine anonyme Klasse mit der Methode invoke, die eine Instanz von ConstructMe erstellt.

Aber aufrufbare Referenz ist bequemer als Lambda in Fällen, in denen Konstruktor eine Menge Parameter hat.

Verwandte Themen