【问题标题】:Kotlin - Higher order functions and type mismatchKotlin - 高阶函数和类型不匹配
【发布时间】:2017-04-10 14:02:23
【问题描述】:

我刚开始学习 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)
    }
}

但是如果我使用 Lambda 一切都解决了

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

【问题讨论】:

    标签: android kotlin


    【解决方案1】:

    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 引入了bound callable references,您可以使用它来引用类的特定实例的函数:

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

    【讨论】:

    • 啊,我明白了,非常感谢,ide 快速修复是在引用方法时包含 MyClass 而不是 this ::save
    【解决方案2】:

    在 Kotlin 1.1 中,你可以使用member reference 来解决这个问题:

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

    如果您使用 Kotlin 1.0.X,请使用 lambda:

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

    【讨论】:

      猜你喜欢
      • 2021-01-10
      • 1970-01-01
      • 1970-01-01
      • 2021-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-25
      相关资源
      最近更新 更多