首页 文章

函数参考和lambda

提问于
浏览
12

尝试使用带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 回答

  • 15

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

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

  • 7

    那很好笑 . “Java反击” . 哈哈

    你的问题很简单:你在 Foo 类中声明了 isOdd ,对吧?那么它不是 function ,而是 method . 这意味着它需要传入 Foo 的实例( this 引用) - 这就是为什么它是2个参数的函数: Foo.(Int) -> Boolean . 语法错误显示 - 对方法的引用类似于 Foo::isOdd .

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

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

    附:关于你的第二个问题 - 该功能尚不支持 .

相关问题