Nothing 不是所有类型的子类型吗?
scala> val array = new Array(5)
array: Array[Nothing] = Array(null, null, null, null, null)
scala> array.map(_ => 42)
<console>:9: error: value map is not a member of Array[Nothing]
array.map(_ => 42)
^
scala> array.filter(_ != 42)
<console>:9: error: value filter is not a member of Array[Nothing]
array.filter(_ != 42)
^
奇怪的是这不起作用。
这是指定的,是功能还是错误?
当您看到涉及 Nothing 的奇怪行为时,这是因为类型推断算法认为它本身插入了 Nothing,因为它是在类型推断期间引入的:如果对类型变量一无所知,那么它就会受到 Any 和 Nothing 的限制。长期以来,我一直在要做的事情清单上,看看我是否可以为此目的引入一个新的仅限内部的底部类型,以便用户级 Nothing 和推理级 Nothing 不会混合在一起,但这是一项非常雄心勃勃的任务。不过,我现在可能已经足够硬核去尝试了。
我怀疑 Scala 不应该让你做那种
Array[Nothing]
实例化。根据定义,周围没有任何实例,但您的数组看起来像是充满了 null 的 Nothing
,但 null 不是 Nothing
的有效值。例如,此操作失败并出现错误 type mismatch; found : Null(null) required: Nothing
val n: Nothing = null
因此,每次你实际上可以欺骗系统相信你终于得到了一个备受追捧的例子时,我预计会遇到麻烦
Nothing
…
这是另一个奇怪的案例。运行这个:
object Main {
class Parametrized[T] { var value: T = _ }
def main(args: Array[String]) {
val p = new Parametrized // typed as Parametrized[Nothing]
val n = p.value // n is now actually an instance of Nothing... isn't it?
println(p.value) // prints null, but null is not an instance of Nothing
println(n) // throws NullPointerException...
}
}
请注意,Scala 数组类型是不变的。因此,
Nothing
作为所有事物的子类型可能并不相关。
此外,
map
和 filter
未在 Array
上定义。 Predef
中的隐式转换用于为数组提供此类方法。
因此编译器无法找到从
Array[Nothing]
到定义了 map
或 filter
的隐式转换。使用 REPL,我实际上可以看到这样的隐式转换应该是可用的:
scala> val conv = implicitly[Array[Nothing] <%< collection.mutable.ArrayOps[Nothing]]
conv: <%<[Array[Nothing],scala.collection.mutable.ArrayOps[Nothing]] = <function1>
scala> conv(new Array[Nothing](5)).filter(_ => true)
res8: Array[Nothing] = Array(null, null, null, null, null)
genericArrayOps
转换。