考虑以下接口
interface EntityConverter<in A, out B> {
fun A.convert(): B
fun List<A>.convert(): List<B> = this.map { it.convert() }
}
我希望在Spring Boot应用程序中使用它,其中特定的实现被注入,使得扩展函数可以在类型上使用。
但是这样不起作用,编译器无法解析扩展函数。
考虑以下接口
interface EntityConverter<in A, out B> {
fun A.convert(): B
fun List<A>.convert(): List<B> = this.map { it.convert() }
}
我希望在Spring Boot应用程序中使用它,其中特定的实现被注入,使得扩展函数可以在类型上使用。
但是这样不起作用,编译器无法解析扩展函数。
EntityConverter
类型的成员函数。您应该查看文档的此部分,了解其工作原理。EntityConverter<A,B>
的实例)A
或List<A>
的实例,其中A
与当前EntityConverter
的第一个类型参数匹配)EntityConverter
引入范围,以便您可以使用常规的 .
语法在其他实例上使用convert:
val converter = object : EntityConverter<Int, String> {
override fun Int.convert() = "#$this"
}
val list = listOf(1, 2, 3)
val convertedList = with(converter) {
list.convert()
}
println(convertedList) // prints [#1, #2, #3]
现在您需要决定这种使用模式是否最适合您的情况。如果您更喜欢没有扩展名的“传统”调用(converter.convert(a)返回一个B),则可以将您的函数声明为常规方法,以接受参数而不是接收方。
奖励:函数接口
顺便说一下,如果在EntityConverter接口前面添加fun关键字,则可以非常容易地创建它的实例,如下所示:
val converter = EntityConverter<Int, String> { "#$this" }
这是因为您的转换器接口只有一个抽象方法,使得使用单个lambda实现变得容易。请参阅有关函数式接口的文档。
A
的“通用”函数。然后就在附近放置列表的扩展方法即可。interface EntityConverter<in A, out B> {
fun convert(a: A): B
}
fun <A, B> EntityConverter<A, B>.convert(list: List<A>): List<B> = list.map { convert(it) }
更新
我之前不知道在Kotlin中可以继承扩展方法,也不知道可以重写它们。所以我的答案只是使用扩展方法的另一种选择。
A
/List<A>
上吗? - Linde_98