Dynamic Kotlin的动态/双重调度限制是什么?

Dynamic Kotlin的动态/双重调度限制是什么?,dynamic,dispatch,kotlin,Dynamic,Dispatch,Kotlin,我刚刚开始探索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:Do

我刚刚开始探索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 } 类动物{ 趣味添加(x:动物)=动物() } 对象马:动物 对象:驴 对象骡子:动物 有趣的马。添加(x:Horse)=马() 有趣的马。添加(x:驴子)=骡子() 趣味主线(args:Array){ 瓦尔h:动物=马 瓦尔d:动物=驴 val child=h+d } 基于上面的代码——我能期望发生什么?我是否因为Horse没有实现add(Animal)而在运行时失败?它能在上述性质的调用中准确地区分它们吗?在这些调用中,被比较的值的编译时类型是Animal(至少在编写时是这样),但它们的运行时类型更为具体?如果我们使用var而不是val,会有什么变化吗

提前谢谢

编辑:修改了核心代码——我看到了第一响应者强调的问题,我没有直截了当地思考。很明显,我还没有真正编译过这个,我仍然在概念层面上进行探索

此外,我将在实际的编译器中试一试,但我担心在某些情况下它会工作,而在其他情况下它不会基于一些我不完全理解的标准。我找不到关于如何在Kotlin中实现动态调度的参考文档(对于Java也不太确定;几个月前我写了一些我认为可以基于JVM文档工作的东西,但是没有,而且我从来没有机会探究确切的原因)


无论如何,再次谢谢你

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

如果他们允许对动物使用马“+”方法, 然后会出现运行时错误,kotlin/java/etc试图阻止这些错误

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

如果另一个线程同时将动物更改为骡子,那么另一个线程更改动物的确切行/时间是不确定的,因此这可能会导致运行时错误


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

因此,下面是一个实际编译的代码版本:

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:驴)
,是静态调度的。这是因为它们基本上被编译为与以下Java代码相同的字节码:

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

顺便说一句,这与Java 8中的默认方法有很大区别,默认方法是根据运行时类型动态调度的,可以被覆盖。

感谢您的反馈;我明白问题所在。我修改了问题代码,希望更合理。非常感谢!这很有道理。我将通过我自己的探索进一步了解这一点。