6

次のコードを想定します。

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?)
}

JavaFX プロパティ ( SimpleIntegerPropertySimpleStringProperty、 ... およびSimpleObjectProperty<T>) をジェネリック クラス コンストラクターの() -> Property<T>引数に渡す::SimpleIntegerPropertyことで、これに::SimpleObjectProperty遭遇しました。

ここでコンパイラを改善したり、型パラメータをコンストラクタ/関数参照に渡すことができるようにすることは可能ですか? ここで単純なラムダ式に対してコンストラクター参照を使用することは理にかなっていますか? コンパイル方法は異なりますか?

4

1 に答える 1

2

はい、ここでコンパイラを改善することは可能です。の型パラメータを推測できますConstructMe。問題https://youtrack.jetbrains.com/issue/KT-10711を参照してください。

非インライン カウンター関数 (この場合は Test のコンストラクター) の場合、ラムダと呼び出し可能なコンストラクターへの参照の間に違いはありません。どちらの場合も、コンパイラはinvokeのインスタンスを作成するメソッドを持つ匿名クラスを作成しますConstructMe

ただし、コンストラクターに多くのパラメーターがある場合は、ラムダよりも呼び出し可能な参照の方が便利です。

于 2016-06-04T20:19:21.050 に答える