成为subtype of every other type允许将假设的Nothing
类型的值传递给任何函数。但是,尽管这样的值可以作为toString()
的接收者,但不能作为unary_!
(以及其他)的接收者。
object Foo {
def dead(q: Nothing): Unit = {
println(q);
q.toString();
((b: Boolean) => !b)(q);
!q; // value unary_! is not a member of Nothing
}
}
这是错误还是功能?
注意:
!(q.asInstanceOf[Boolean])
答案 0 :(得分:2)
您不需要上流。您只需将某种具有方法unary_!
的类型归因于此:
def dead(q: Nothing): Unit = {
!(q: Boolean)
}
没有显式类型说明,方法unary_!
根本无法解析,因为即使Nothing
是Boolean
的子类型,它也不是< Boolean
的em> subclass ,因此编译器无法在unary_!
的继承层次结构中找到方法Nothing
。
您可以定义此类方法和函数的事实也不是错误。以下是一个完全有效的程序,该程序使用输入类型为Nothing
的函数来产生完全有意义的结果0
,而不会引发任何错误或类似的结果:
def foo[X](xs: List[X], f: (Int, X) => Int) = {
xs.foldLeft(0)(f)
}
foo(Nil, (i: Int, n: Nothing) => 42)
在类型系统中存在Nothing
是一个非常好的主意,因为它是一个初始对象(对于每个其他类型A
,只有一个功能Nothing => A
),并且它简化了很多事情,因为它不会强迫您处理各种奇怪的极端情况。
答案 1 :(得分:0)
无是其他所有类型的子类型(包括scala.Null);没有这种类型的实例
换句话说,没有类型Nothing
的值。因此,与您的问题中的陈述相反,您不能将Nothing
类型的值传递给任何函数(甚至假设地),因为根据定义,它不存在。同样,它也不是任何方法的接收者,因为它再次不存在。
因此,该错误(如果有的话)是编译器不会警告您您创建了一个永远无法调用的函数。
在这种情况下,println(q)
起作用是因为Nothing
是Any
的子类型,而q.toString
起作用是由于AnyRef
到{{ 1}}支持Object
。内联函数将toString
转换为q
也可以,但是Boolean
不支持Object
,因此unary_!
无法编译。