我刚刚开始学习 kotlin,正在努力理解高阶函数如何确定类型,我经常看到这种错误
错误:类型不匹配:推断的类型是 KFunction2,但(字符串(->单位是预期的
上述错误是由以下原因引起的
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)
}
}
我的超级类
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,请使用 lambda:
fun saveValue(potentialValue: String) {
super.processValue(potentialValue, (arg) -> save(arg))
}