简体   繁体   English

Kotlin-高阶函数和类型不匹配

[英]Kotlin - Higher order functions and type mismatch

Im just beginning to learn kotlin and am struggling to understand how the higher-order functions determine types, i am regularly seeing this kind of error 我刚刚开始学习Kotlin,并且正在努力了解高阶函数如何确定类型,我经常看到这种错误

Error: Type mismatch: inferred type is KFunction2 but (String) -> Unit was expected 错误:类型不匹配:推断的类型为KFunction2,但预期为(String)->单位

The above error is caused by the following 上面的错误是由以下原因引起的

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

However if i use a Lambda all is solved 但是,如果我使用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 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 is a KFunction2 , meaning it has two parameters. MyClass::save是一个KFunction2 ,意味着它有两个参数。 This is because this expression refers to the method of the class instead of referring to a method of the current instance that you have. 这是因为此表达式引用的是类的方法,而不是引用的当前实例的方法。 This means that when you're calling it, you have to pass in a MyClass instance to call it on, as well as the String parameter. 这意味着,在调用它时,您必须传递一个MyClass实例以及String参数来对其进行调用。 This makes it a (MyClass, String) -> Unit function, which causes the type mismatch. 这使其成为(MyClass, String) -> Unit函数,从而导致类型不匹配。

For example, this is how you could call it: 例如,这是您可以这样称呼的方式:

class MyClass {

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

    fun save(value: String) {
        // ...
    }

}

As for what you're looking for, Kotlin 1.1 introduced bound callable references , which you can use to refer to a function of a specific instance of a class: 至于您要寻找的内容,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)
    }

}

In Kotlin 1.1, you can use member reference to solve this problem: 在Kotlin 1.1中,您可以使用成员引用来解决此问题:

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

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM