为什么映射/过滤器...不适用于无数组?

问题描述 投票:0回答:3

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)
             ^

奇怪的是这不起作用。

这是指定的,是功能还是错误?

arrays scala dictionary higher-order-functions
3个回答
7
投票

当您看到涉及 Nothing 的奇怪行为时,这是因为类型推断算法认为它本身插入了 Nothing,因为它是在类型推断期间引入的:如果对类型变量一无所知,那么它就会受到 Any 和 Nothing 的限制。长期以来,我一直在要做的事情清单上,看看我是否可以为此目的引入一个新的仅限内部的底部类型,以便用户级 Nothing 和推理级 Nothing 不会混合在一起,但这是一项非常雄心勃勃的任务。不过,我现在可能已经足够硬核去尝试了。


4
投票

我怀疑 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...
  }

}

4
投票

请注意,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
转换。

© www.soinside.com 2019 - 2024. All rights reserved.