Kotlin 如何从泛型代码调用扩展函数
给定以下类和扩展函数Kotlin 如何从泛型代码调用扩展函数,kotlin,Kotlin,给定以下类和扩展函数 class Foo class Bar fun Foo.run() = "Foo.run" fun Bar.run() = "Bar.run" fun main(args: Array<String>) { val x = listOf(Foo(), Bar()) val y = x.map({a -> a.run()}) //compiler error println("Hello, world!") } class-F
class Foo
class Bar
fun Foo.run() = "Foo.run"
fun Bar.run() = "Bar.run"
fun main(args: Array<String>) {
val x = listOf(Foo(), Bar())
val y = x.map({a -> a.run()}) //compiler error
println("Hello, world!")
}
class-Foo
分类栏
fun Foo.run()=“Foo.run”
有趣的Bar.run()=“Bar.run”
趣味主线(args:Array){
val x=listOf(Foo(),Bar())
val y=x.map({a->a.run()})//编译器错误
println(“你好,世界!”)
}
是否可以以通用方式调用run
不知何故,这是在通过接口扩展类时模仿Swift的协议
s和扩展
s的一种尝试,或者是不可能的或不希望的,您可以这样做
fun <T> T.run() = "run"
这样,只有Foo
和Bar
的实例才能使用run
但是如果我是你,我会让
run
成为Bla
的一个成员函数,你只需要一个公共类型,然后扩展这个。一个简单的标记界面将有助于:
interface Common
class Foo: Common
class Bar: Common
fun Common.run() = "run"
fun main(args: Array<String>) {
val x = listOf(Foo(), Bar())
val y = x.map {a -> a.run() }
}
您的列表具有
Foo
和Bar
--Any
的最低常用类型,您应该在调用run
方法之前检查lambda中的类型:
class Foo
class Bar
fun Foo.run() = "Foo.run"
fun Bar.run() = "Bar.run"
fun main(args: Array<String>) {
val x = listOf(Foo(), Bar())
val y = x.map({ a ->
when (a) {
is Foo -> a.run()
is Bar -> a.run()
else -> {
/* ignore */
}
}
})
println("Hello, world!")
}
将打印[Any.run,Any.run]
但是使用对此的引用,您可以为您的函数提供如下数据:
class Foo
class Bar
inline fun Any.run() = this::class.simpleName + ".run"
fun main(args: Array<String>) {
val x = listOf(Foo(), Bar())
val y = x.map(Any::run)
println(y)
}
将打印[Foo!!!.run,Bar!!!.run,Unknown.run]
为什么不给他们一个通用类型(例如接口)并扩展这个类型呢?不适用于密封类您可以使用密封类,请参阅我的回答我已经稍微更新了我的uestion,因为我的初始示例似乎表明了一个通用函数impl。这是不可能的,除非你乐于使用反射,否则我想表达“任何类型都有(不同的)run
函数”,而不是限制它。
class Foo
class Bar
fun Foo.run() = "Foo.run"
fun Bar.run() = "Bar.run"
fun main(args: Array<String>) {
val x = listOf(Foo(), Bar())
val y = x.map({ a ->
when (a) {
is Foo -> a.run()
is Bar -> a.run()
else -> {
/* ignore */
}
}
})
println("Hello, world!")
}
class Foo
class Bar
fun Foo.run() = "Foo.run"
fun Bar.run() = "Bar.run"
fun main(args: Array<String>) {
val x = listOf(Foo(), Bar())
val y = x.map({ a ->(a as? Foo)?.run() ?: (a as? Bar)?.run() })
println("Hello, world!")
}
class Foo
class Bar
fun Foo.run() = "Foo.run"
fun Bar.run() = "Bar.run"
fun Any.run() = "Any.run" // this is type erasured version of 'inline fun <reified T> T.run() = T::class.simpleName+".run"'
fun main(args: Array<String>) {
val x = listOf(Foo(), Bar())
val y = x.map(Any::run)
println(y)
}
class Foo
class Bar
inline fun Any.run() = this::class.simpleName + ".run"
fun main(args: Array<String>) {
val x = listOf(Foo(), Bar())
val y = x.map(Any::run)
println(y)
}
class Foo
class Bar
fun Foo.run() = "Foo!!!.run"
fun Bar.run() = "Bar!!!.run"
fun Any.run() = when(this){
is Foo -> run()
is Bar -> run()
else -> { "Unknown.run" }
}
fun main(args: Array<String>) {
val x = listOf(Foo(), Bar(), Any())
val y = x.map({ a -> a.run()
})
println(y)
}