2017-04-10 54 views
0

我只是开始学习科特林和我在努力了解高阶函数如何确定类型的,我经常看到这种错误科特林 - 高阶函数和类型不匹配

​​

上述错误是所引起的下列

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

回答

2

MyClass::saveKFunction2,这意味着它有两个参数。这是因为此表达式引用类的方法而不是引用当前实例的方法。这意味着当您调用它时,必须传入一个MyClass实例来调用它,以及String参数。这使它成为(MyClass, String) -> Unit函数,这会导致类型不匹配。

例如,你这是怎么可以把它称为:

class MyClass { 

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

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

} 

至于你在找什么,科特林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) 
    } 

} 
+1

啊,我看到非常感谢你的IDE快速的解决办法是包括'MyClass'而不是'this'引用的方法,只是'时: :save' –

2

在科特林1.1,你可以使用member reference来解决这个问题:

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

如果使用科特林1.0.X,使用拉姆达:

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