Kotlin - функция перегрузки с лямбда-аргументами - PullRequest
0 голосов
/ 16 мая 2018

Предположим, я хочу иметь функцию, которая проверяет, отличается ли значение свойства в двух заданных объектах. Если это так, то должен быть выполнен обработчик лямбды.

fun <P>onChange(oldObj: P, newObj: P, select: (P) -> Any, handler: (P) -> Unit) {
   val newValues = select(newObj)
   val oldValues = select(oldObj)
   if (oldValues != newValues) { handler(newObj) }
}

Он прекрасно работает для следующих случаев использования:

data class TestObj(
    val foo: String,
    val bar: String? = null
)

val oldObj = TestObj(foo = "foo")
val newObj = TestObj(foo = "foo1", bar = "bar")

onChange(oldObj, newObj, { it.foo }) {
    print("foo did change: ${it.foo}")
}

Теперь я хочу проверить, изменилось ли bar. Если я попытаюсь перегрузить функцию как

fun <P>onChange(oldObj: P, newObj: P, select: (P) -> Any?, handler: (P) -> Unit) {
...
}

компилятор создает исключение Duplicate method name&signature.

Как перегрузить функцию или изменить сигнатуру для поддержки select лямбда-выражения, которое может возвращать необязательный параметр?

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

(P) -> Any? является подтипом (P) -> Any, поэтому, если у вас просто есть

fun <P>onChange(oldObj: P, newObj: P, select: (P) -> Any?, handler: (P) -> Unit)

вы можете передать (P) -> Any там. Конечно, с перегрузкой вы можете иметь две разные реализации, но если поведение на самом деле отличается, это кажется очень плохой идеей:)

0 голосов
/ 16 мая 2018

Измените имя. Они имеют одинаковую сигнатуру JVM, потому что обнуляемые типы не существуют на уровне байтового кода. Это функция Kotlin, применяемая во время компиляции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...