微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 kotlin 中将 lambdas 与函数式接口一起使用并直接将 lambda 赋值给 var

如何解决如何在 kotlin 中将 lambdas 与函数式接口一起使用并直接将 lambda 赋值给 var

我有这个代码

package org.medianik.kotlindoc

fun main(){
    val creator:Creatable = toCreatable(::Created)// Ok. Compiles,and works fine
    val creator1:Creatable = ::Created // Compilation error
    val creator2:Creatable = ::Created as Creatable // ok enough to compile,but there is runtime exception
    val c = creator.create(5)
    val creator3:Creatable = toCreatable(c::doSmth1) // Ok. Compiles,works fine
    val creator4:Creatable = c::doSmth1 // Compilation error
    val creator5:Creatable = c::doSmth1 as Creatable // Again ok enough to compile,but there is runtime exception
    val creator6:Creatable = Creatable { i -> Created(i) } // Works fine,but that's not what I want
}

fun toCreatable(c:Creatable) = c

fun interface Creatable{
    fun create(i: Int) : Created
}
class Created(private var i: Int){
    fun doSmth1(add: Int): Created{
        return this.also { i+=add }
    }
}

creator2 的例外:

Exception in thread "main" java.lang.classCastException: class org.medianik.kotlindoc.MainKt$main$creator2$1 cannot be cast to class org.medianik.kotlindoc.Creatable (org.medianik.kotlindoc.MainKt$main$creator2$1 and org.medianik.kotlindoc.Creatable are in unnamed module of loader 'app')

creator5 的例外:

Exception in thread "main" java.lang.classCastException: class org.medianik.kotlindoc.MainKt$main$creator5$1 cannot be cast to class org.medianik.kotlindoc.Creatable (org.medianik.kotlindoc.MainKt$main$creator5$1 and org.medianik.kotlindoc.Creatable are in unnamed module of loader 'app')

我不知道如何使creator1/4 与方法引用一起工作。有什么方法可以让它们工作吗?因为这对我来说似乎毫无意义:如果您将方法引用作为参数传递给函数 - 它会转换为接口,否则不会。它是如何工作的?

是否有一些特殊的函数到接口的转换?

解决方法

我将您的代码复制到 IntelliJ 中,但在行中也出现错误

 val creator:Creatable = toCreatable(::Created)
 val creator3:Creatable = toCreatable(c::doSmth1)

问题是,Creatable 是一个命名接口,它具有与类 Created 相同的方法签名,但该类没有实现该接口。

请注意,函数不实现接口,即使它们有签名。

你可以用函数类型来代替接口。请注意,这并不相同,但它们的处理方式几乎相同。

typealias Creatable = (Int) -> Created

或者你可以编写一个接受这种函数类型的包装器:

fun toCreatable(c:(Int) -> Created) = object: Creatable {
    override fun create(i: Int): Created {
        return c(i)
    }
}

这个函数接受一个函数并返回一个实际实现接口的对象。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。