Как передать параметр типа в ссылку на конструктор универсального класса?

Предположим, следующий код:

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 (SimpleIntegerProperty, SimpleStringProperty,... а также SimpleObjectProperty<T>) к универсальным конструкторам классов () -> Property<T> аргумент, где прохождение ::SimpleIntegerProperty работает без проблем, пока ::SimpleObjectProperty не так, как в примере кода выше.

Можно ли улучшить компилятор здесь или разрешить передачу параметров типа в ссылки на конструктор / функцию? Имеет ли смысл здесь использовать ссылки на конструктор поверх простых лямбда-выражений? Это компилируется по-другому?

1 ответ

Решение

Да, здесь можно улучшить компилятор. Может выводить параметр типа для ConstructMe, Смотрите выпуск https://youtrack.jetbrains.com/issue/KT-10711.

Для не встроенной функции ounter (в данном случае это конструктор Test) нет разницы между лямбда и вызываемой ссылкой на конструктор. В обоих случаях компилятор создает анонимный класс, который имеет метод invoke это создает экземпляр ConstructMe,

Но вызываемая ссылка более удобна, чем лямбда в случаях, когда конструктор имеет много параметров.

Другие вопросы по тегам