Котлин – Функции более высокого порядка и несоответствие типов

Я только начинаю изучать kotlin и изо всех сил пытаюсь понять, как функции более высокого порядка определяют типы, я регулярно вижу такую ​​ошибку

Ошибка: Тип несоответствия: предполагаемый тип – KFunction2, но (String) -> Ожидалось устройство

Вышеупомянутая ошибка вызвана следующим

class MyClass(private val valueChangeListener: MyValueChangeListener, public val storage: MyStorage): MySuperClass { fun saveValue(potentialValue: String) { super.processValue(potentialValue, MyClass::save) } fun save(value: String){ storage.storeValue(value) valueChangeListener.onValueChanged(value) } } 

Однако, если я использую Лямбду, все решено

 class MyClass(private val valueChangeListener: MyValueChangeListener, public val storage: MyStorage): MySuperClass { fun saveValue(potentialValue: String) { super.processValue(potentialValue, super.processValue(potentialValue, { value: String -> save(value) }) } fun save(value: String){ storage.storeValue(value) valueChangeListener.onValueChanged(value) } } 

MySuperClass

 open class MySuperClass { private fun cleanseValue(value: String) : String { return value.toUpperCase().replace(" ", "").replace("-", "") } protected fun processValue(potentialValue: String, saveFunction: (String) -> Unit){ saveFunction(cleanseValue(potentialValue)) } } 

MyClass::save – это KFunction2 , то есть имеет два параметра. Это связано с тем, что это выражение относится к методу класса вместо обращения к методу текущего экземпляра, который у вас есть. Это означает, что когда вы вызываете его, вы должны передать экземпляр MyClass для его вызова, а также параметр String . Это делает его функцией (MyClass, String) -> Unit , что вызывает несоответствие типа.

Например, так вы можете это назвать:

 class MyClass { fun test() { val s = MyClass::save s(this, "some value") } fun save(value: String) { // ... } } 

Что касается того, что вы ищете, Kotlin 1.1 представил связанные вызываемые ссылки , которые вы можете использовать для ссылки на функцию определенного экземпляра класса:

 class MyClass(private val valueChangeListener: MyValueChangeListener, public val storage: MyStorage): MySuperClass() { fun saveValue(potentialValue: String) { super.processValue(potentialValue, this::save) // see here } fun save(value: String){ storage.storeValue(value) valueChangeListener.onValueChanged(value) } } 

В Kotlin 1.1 вы можете использовать ссылку участника для решения этой проблемы:

 fun saveValue(potentialValue: String) { super.processValue(potentialValue, this::save) } 

Если вы используете Kotlin 1.0.X, используйте лямбда:

 fun saveValue(potentialValue: String) { super.processValue(potentialValue, (arg) -> save(arg)) }