如何在Kotlin中用泛型定义功能界面?

问题描述 投票:4回答:1

我正在学习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

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

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边界的泛型参数?

kotlin
1个回答
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

© www.soinside.com 2019 - 2024. All rights reserved.