How to pass a type parameter to a link to a common class constructor?

Assume the following code:

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

I came across this by passing JavaFX properties ( SimpleIntegerProperty , SimpleStringProperty , ... and SimpleObjectProperty<T> ) to the class constructor argument () -> Property<T> , where passing ::SimpleIntegerProperty works without problems, while ::SimpleObjectProperty fails, as in the above code example.

Is it possible to improve the compiler here or allow passing type parameters for references to the constructor / function? Does it make sense to use constructor references for simple lambda expressions here? Will it compile differently?

+5
source share
1 answer

Yes, here you can improve the compiler. It can infer a type parameter for ConstructMe . See Question https://youtrack.jetbrains.com/issue/KT-10711 .

For the non-inline ounter function (in this case, the Test constructor), there is no difference between the lambda and the called constructor reference. In both cases, the compiler creates an anonymous class that has an invoke method that creates an instance of ConstructMe .

But the called link is more convenient than the lambda in cases where the constructor has many parameters.

+2
source

All Articles