Если вы хотите сохранить различные функции вместе, вам нужно обработать тип параметра T
с out
дисперсией. Это означает, что T
используется только в выводе класса. На практике это означает, что преобразования Spec<Derived>
-> Spec<Base>
разрешены, если Derived
расширяет / реализует Base
.
Без такого ограничения типы функций не связаны, и поэтому вы не можете хранить их в общем массиве (varargs - просто синтаксический сахар для параметров массива).
Пример:
class Spec<out T>
fun createStringSpec() = Spec<String>()
fun createIntSpec() = Spec<Int>()
fun <T> ifNotNullCreateSpec(vararg pairs: Pair<T, () -> Spec<T>>) = Unit
fun main() {
ifNotNullCreateSpec("asdf" to ::createStringSpec, 5 to ::createIntSpec)
}
С параметром T
, таким как (T) -> Spec<T>
, тип T
также появляется на входе типа функции. Это означает, что вы больше не можете хранить типы функций вместе, потому что они принимают параметры разных типов - с каким типом вы вызываете такую функцию?
Что вам нужно сделать, это найти наиболее распространенный знаменатель. Одним из примеров является принятие параметра Any
и выполнение проверки / отправки во время выполнения для фактического типа.
Смотрите также мой недавний ответ здесь: https://stackoverflow.com/a/55572849