首页 文章

Kotlin的动态/双重调度有哪些限制?

提问于
浏览
1

我刚刚开始探索Kotlin,我很好奇它超越了Java的核心动态绑定/调度语义 .

假设我编写的代码看起来像这样:

class Animal {
        fun add(x:Animal) = Animal()
    }

    object Horse : Animal
    object Donkey : Animal
    object Mule : Animal

    fun Horse.add(x:Horse) = Horse()
    fun Horse.add(x:Donkey) = Mule()

    fun main(args : Array) {
        val h:Animal = Horse
        val d:Animal = Donkey
        val child = h + d
    }

基于上面的代码 - 我可以期待发生什么?我是否在运行时失败,因为Horse没有实现添加(动物)?它是否可以在上述性质的调用中准确区分它们,其中被比较的值的编译时类型是Animal(至少是写入的),但它们的运行时类型更具体?如果我们使用var而不是val,它会改变什么吗?

提前致谢 .

编辑:修改核心代码 - 我看到第一响应者强调的问题,我没有直接思考 . 显然我还没有编译过这个,我仍然在概念层面进行探索 .

另外,我会在实际的编译器中给它一个镜头,但是我担心会出现它工作的情况,而其他情况则不会基于我不完全理解的某些标准 . 我无法找到关于如何在Kotlin中实现动态调度的参考文档(对于Java来说也不确定它是什么意思;几个月前我写了一些我认为可以基于JVM文档工作的东西,但它没有不,我从来没有机会探究到底为什么 .

无论如何再次感谢!

2 回答

  • 0

    所以这是一个实际编译的代码版本:

    fun main(vararg args: String) {
        val h:Animal = Horse
        val d:Animal = Donkey
        val child = h + d
        println(child)
    }
    
    open class Animal {
        fun plus(x:Animal) = Animal()
    }
    
    object Horse : Animal()
    object Donkey : Animal()
    object Mule : Animal()
    
    fun Horse.plus(x:Horse) = Horse
    fun Horse.plus(x:Donkey) = Mule
    

    结果是“Animal @ 1906bcf8” .

    据我所知,扩展方法,即 Horse.plus(x:Horse)Horse.plus(x:Donkey) ,是静态调度的 . 那是因为它们被基本编译为与以下Java代码相同的字节代码:

    static Horse plus(Horse $receiver, Horse x) {
        return Horse.INSTANCE;
    }
    

    顺便说一句,这与Java 8中的默认方法有很大不同,它们是基于运行时类型动态调度的,可以被覆盖 .

  • 4

    这段代码根本不可编译,因为Animal没有任何“”运算符 .

    如果他们允许在Animal上使用Horse“”方法,那么你会得到运行时错误,kotlin / java / etc . 试图阻止 .

    Kotlin不会使用运行时类型来解决方法和内容,因为有可能产生运行时错误 .

    如果另一个线程在此期间将Animal更改为Mule,另一个线程更改Animal的确切行/时间不确定,那么这可能会导致运行时错误 .

    Val或var在这种情况下不会改变任何东西 .

相关问题