Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin 如何从泛型代码调用扩展函数_Kotlin - Fatal编程技术网

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)
}