我知道Scala没有什么是底层类型。当我看到API时,它会扩展到" Any"这是层次结构中的顶层。
既然Scala不支持多重继承,我们怎么能说它是底层类型。换句话说,它不直接继承所有类或特征,如Seq,List,String,Int等。如果是这种情况我们怎么能说它是所有类型的底部?
我的意思是,如果我们能够将List [Nothing](Nil)分配给List [String],因为List在scala中是协变的,因为Nothing和String类型之间没有直接关联。我们知道什么都不是底层类型,但我很难看到String和Nothing之间的关系,就像我在上面的例子中所说的那样。
谢谢&问候, 穆罕默德
答案 0 :(得分:3)
现在,因为Scala不支持多重继承
Scala确实支持多重继承,使用trait mixin。这当前不是可交换的,即类型A with B
与B with A
不一样(这将与Dotty一起发生),但它仍然是多重继承的形式,实际上是Scala&#39之一;它的优点,因为它通过线性化规则解决了钻石问题。
顺便说一下,Null
是另一个底层类型,继承自Java(也可以说它有一个Nothing
底部类型,因为你可以在任何可能的地方抛出运行时异常。) / p>
我认为您需要区分类继承和类型边界。将Nothing
定义为底部类型没有矛盾,尽管它没有明确地"从您想要的任何类型继承,例如List
。它更像是一种能力,即抛出异常的能力。
如果我们能够将List [Nothing](Nil)分配给List [String],因为List在scala中是协变的,因为Nothing和String类型之间没有直接关联
是的,底部类型的想法是Nothing
也是(在许多其他事物中)String
的子类型。所以你可以写
def foo: String = throw new Exception("No")
这只能起作用,因为Nothing
(抛出异常的类型)比声明的返回类型String
更具体。
答案 1 :(得分:3)
tl; dr summary :Nothing
是每种类型的子类型,因为规范是这样说的。它无法从语言中解释。每种语言(或至少几乎每种语言)都有一些无法用语言解释的核心内容,例如: java.lang.Object
没有超类,即使每个类都有一个超类,因为即使我们不写一个extends
子句,该类也会隐式获得一个超类。或Ruby中的“bootstrap paradox”,Object
是Class
的实例,但Class
是Object
的子类,因此Object
是间接的本身的实例(甚至更直接:Class
是Class
的实例。)
我知道Scala没有什么是底层类型。当我看到API时,它从“Any”扩展,这是层次结构中的顶层。
既然Scala不支持多重继承,我们怎么能说它是底层类型。
有两种可能的答案。
简单明了的答案是:because the spec says so。规范说Nothing
是所有类型的子类型,因此Nothing
是所有类型的子类型。怎么样?我们不在乎。规范说它是如此,所以就是这样。让编译器设计者担心如何在他们的编译器中表示这个事实。你关心Any
如何超级?您是否关心编译器内部如何表示def
?
稍长的答案是:是的,这是真的,Nothing
继承自Any
而仅来自Any
。但!继承与子类型不同。在Scala中,继承和子类型紧密相连,但它们并不是一回事。 Nothing
只能从一个类继承的事实并不意味着它不能是多个类型的子类型。类型与类不同。
事实上,非常具体,规范甚至没有说Nothing
是所有类型的子类型。它只说Nothing
conforms to all types。
换句话说,它不直接继承所有类或特征,如Seq,List,String,Int等。如果是这种情况我们怎么能说它是所有类型的底部?
同样,我们可以这么说,因为规范说我们可以这么说。
我们怎么能说def
定义了一个方法?因为the spec says so。我们如何说a b c
与a.b(c)
的含义相同,a b_: c
与{ val __some_unforgeable_id__ = a; c.b_:(__some_unforgeable_id__) }
的含义相同?因为the spec says so。我们怎么能说""
是一个字符串而''
是一个字符?因为the spec says so。
我的意思是,如果我们能够将List [Nothing](Nil)分配给List [String],因为List在scala中是协变的,因为Nothing和String类型之间没有直接关联。
是的,是类型Nothing
和String
之间的直接关联。 Nothing
是String
的子类型,因为Nothing
是所有类型的子类型,包括String
。
正如我们所知,没有什么是底层类型,但我很难看到String和Nothing之间的关系,如上例所述。
String
和Nothing
之间的关系是Nothing
是String
的子类型。为什么?因为规范是这样说的。
编译器知道Nothing
是String
的子类型,就像它知道的1
Int
的实例一样,并且有+
方法,甚至但是如果你看一下Scala标准库的源代码the Int
class is actually abstract and all its methods have no implementation。
Someone, somewhere wrote some code within the compiler that knows how to handle adding two numbers,即使这些数字实际上表示为JVM原语,甚至不存在于Scala对象系统中。以同样的方式,someone, somewhere wrote some code within the compiler that knows that Nothing
is a subtype of all types即使the source code of Nothing
中没有表示这个事实(甚至不能代表)。