Kotlin-“ where”通用约束的问题

Ale*_*ich 2 generics kotlin

ClassAClassB,还有如下所示的函数:

fun <T> doSomething(arg: T) where T: ClassA, T: ClassB {  }
Run Code Online (Sandbox Code Playgroud)

当我调用此函数作为参数传递类ClassC的对象时,它可以完美编译并按预期工作:

class ClassC: ClassA(), ClassB
Run Code Online (Sandbox Code Playgroud)

但是当我有一个类型的对象Any并执行以下操作时:

if (arg is ClassA && arg is ClassB) {
    doSomething(arg)
}
Run Code Online (Sandbox Code Playgroud)

编译器不会编译它并说

None of the following functions can be called with the arguments supplied
Run Code Online (Sandbox Code Playgroud)

我希望智能广播能够完成工作,但事实并非如此。请告诉我怎么了。提前致谢。

Ale*_*hin 6

聪明的演员工作,而不是您期望的那样。
为了帮助您理解,请检查:

if (arg is ClassA && arg is ClassB) {
    doSomething(arg)
}
Run Code Online (Sandbox Code Playgroud)

转换为:

if (arg is ClassA) {
    if (arg is ClassB) {
        doSomething(arg) // Only what's common between ClassA and ClassB is there
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,由于ClassA和之间没有共同之处ClassB,因此Any可以推断出。这不是您所期望的。

您可以强制强制转换,当然:

if (arg is ClassA && arg is ClassB) {
    doSomething(arg as ClassC)
}
Run Code Online (Sandbox Code Playgroud)

但这可能也不起作用:

class ClassC: ClassA(), ClassB 

class ClassD: ClassA(), ClassB // This will cause ClassCast exception
Run Code Online (Sandbox Code Playgroud)

最后,仅在以下情况下使用这种约束类型才有意义:

open class ClassC: ClassA(), ClassB

class ClassD: ClassC()

class ClassE: ClassC()
Run Code Online (Sandbox Code Playgroud)

现在,引发问题的原因Any推断。它不应该是Nothing,因为没有什么共同之处?

在这里,我们需要记住Kotlin类型系统是如何工作的。

如果您编写如下内容:

open class ClassA

open class ClassB
Run Code Online (Sandbox Code Playgroud)

您实际的意思是:

open class ClassA : Any

open class ClassB : Any
Run Code Online (Sandbox Code Playgroud)

这就是我们推断的共同祖先。

Nothing另一方面,是类层次结构底部的最终类。因此,没有一个类可以继承。