如何在Kotlin中使用泛型定义功能接口?

时间:2019-03-25 19:10:54

标签: kotlin

我正在学习Kotlin,我在功能上遇到了一些麻烦。 我正在尝试创建带有泛型参数的功能接口之类的东西。 在Java中,我将创建以下内容:

@FunctionalInterface
public interface Foo<T extends Bar> {
    String something(T arg);
}

然后我可以在其他类似地方使用它(假设Person扩展了Bar


Foo<Person> f = p -> p.toString();

您如何用Kotlin编写此书?

我尝试的第一件事是使用这样的类型别名:

typealias Foo<T> = (T) -> String

但是,当我将绑定添加到类型参数时,它停止工作:

typealias Foo<T: Bar> = (T) -> String  // Error: Bounds are not allowed on type alias parameters

第二种方法是编写一个扩展函数类型的接口:

interface Foo<T: Bar> : (T) -> String

但是,现在我不知道如何使用此实例化lambda函数。当我像这样从中创建类时,它将起作用:

class Something: Foo<Person> {
    override fun invoke(p: Person): String {
        return p.toString()
    }
}

val f = Something()

但这是一个很大的开销,我确信必须有一个更好的解决方案。

那么我如何定义一个可以被许多支持通用参数且在kotlin中有界限的函数重用的函数签名?

1 个答案:

答案 0 :(得分:4)

在大多数时候(总是?),在接收它的函数的参数中定义lambda的类型就足够了。

例如:

open class Bar
class Person: Bar()

var f = { p: Person -> p.toString() }

fun <T : Bar> withFoo(block: (T) -> String) { }
fun <T : Bar> otherFoo(block: (T) -> String) { }   

fun main() {
    withFoo(f)
    otherFoo(f)
}

Kotlin文档指出的相同方式: “由于Kotlin具有适当的功能类型,因此不需要将功能自动转换为Kotlin接口的实现,因此不受支持。”

请参见https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions