函数参考和lambda

时间:2015-11-09 19:14:58

标签: kotlin

我尝试在kotlin中使用lambdas / function引用时遇到编译错误:

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:带有a的可调用引用的左侧   接收器参数不能为空。请指定的类型   接收器之前' ::'明确地

我不确定错误是什么,也不确定我应该在' ::'

之前明确说明的类型

另一个问题: 我可以在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 个答案:

答案 0 :(得分:16)

关于第二个例子:是的,自Kotlin 1.1以来支持bound function reference语法,因此您可以像Java一样编写bar::isOdd

在第一个示例中,错误试图说isOdd实际上是两个参数(类型FooInt)的函数,并且传递一个函数需要两个参数作为参数,其类型是一个参数的函数是不允许的。要使示例编译,您可以使isOdd成为顶级函数或本地函数,这将使其成为Int类型的一个参数的函数。或者,如果您使用Kotlin 1.1+,请使用绑定函数参考语法,只需编写this::isOdd

答案 1 :(得分:7)

这很有趣。 “Java反击”。哈哈

您的问题很简单:您在班级isOdd中宣布了Foo,对吧?那么它不是功能,而是方法。这意味着它需要传递Foo的实例(this引用) - 这就是为什么它是2个参数的函数:Foo.(Int) -> Boolean。语法错误显示 - 对方法的引用类似于Foo::isOdd

无论如何,声明一个不使用该对象的非静态方法即使在Java中也是反模式,你不同意吗?

可以通过声明没有类的自由函数或将其作为扩展来解决问题:fun Int.isOdd()

P.S。关于你的第二个问题 - 该功能尚不支持。

相关问题