尝试使用带kotlin的lambdas /函数引用时,我遇到编译错误:
class Foo {
fun getFilteredList(){
val numbers = listOf(1, 2, 3)
numbers.filter(::isOdd) // prints [1, 3]
}
fun isOdd(x: Int): Boolean = x % 2 != 0
}
但是我得到一个编译时错误,说类型不匹配:
错误:(18,16)Gradle:类型推断失败:内联乐趣kotlin.Iterable.filter(谓词:(T) - > kotlin.Boolean):kotlin.List不能应用于receiver:kotlin.List参数:(kotlin .reflect.KFunction2)错误:(18,23)Gradle:类型不匹配:推断类型是kotlin.reflect.KFunction2但是(kotlin.Int) - > ???预期错误:(18,23)Gradle:类型不匹配:推断类型是kotlin.reflect.KFunction2但是(kotlin.Int) - > kotlin.Boolean是预期错误:(18,25)Gradle:左边的一个带有receiver参数的可调用引用不能为空 . 请明确指定'::'之前的接收器类型
我不确定错误是什么,也不确定我应该在'::'之前明确指定的类型
另一个问题:我可以在kotlin中使用另一个对象函数作为参考吗?像这样的东西:
class Bar {
fun isOdd(x: Int): Boolean = x % 2 != 0
}
class Foo {
fun getFilteredList(){
val bar = Bar()
val numbers = listOf(1, 2, 3)
numbers.filter(bar::isOdd) // Use Bar's method
}
}
2 回答
在第二个例子中:是的,自Kotlin 1.1以来支持bound function reference语法,因此您可以像Java一样编写
bar::isOdd
.在第一个示例中,错误试图说
isOdd
实际上是两个参数(类型Foo
和Int
)的函数,并且传递一个函数,该函数将两个参数作为参数,其类型是一个参数的函数是不允许的 . 要使示例编译,可以使isOdd
成为顶级函数或本地函数,这将使其成为Int
类型的一个参数的函数 . 或者,如果您使用Kotlin 1.1,请使用绑定函数参考语法并简单地编写this::isOdd
.那很好笑 . “Java反击” . 哈哈
你的问题很简单:你在
Foo
类中声明了isOdd
,对吧?那么它不是 function ,而是 method . 这意味着它需要传入Foo
的实例(this
引用) - 这就是为什么它是2个参数的函数:Foo.(Int) -> Boolean
. 语法错误显示 - 对方法的引用类似于Foo::isOdd
.无论如何,声明一个不使用该对象的非静态方法即使在Java中也是反模式,你不同意吗?
可以通过声明没有类的自由函数或使其成为扩展来解决问题:
fun Int.isOdd()
附:关于你的第二个问题 - 该功能尚不支持 .