在Scala中测试数组是否空虚

时间:2017-01-31 17:22:52

标签: scala scala-collections

关于 如何测试数组空虚的问题(def unique(objects): return list(sorted(set(objects))) 做得很好)。相反,我的问题是,为什么

arr.length == 0

工作和

scala> Array().isEmpty
res1: Boolean = true

工作,但

scala> val x = Array[String]()
x: Array[String] = Array()
scala> x.isEmpty
res2: Boolean = true

没有?

2 个答案:

答案 0 :(得分:4)

正如@MichaelZajac指出的那样,Nothing是一切的子类型(其对应Any是一切的超类型)。特别是它也是AnyRef的子类型。事实上,有一个更普遍的genericArrayOps没有任何类型约束(例如Array[Any]().isEmpty工作)!允许您使用isEmpty 的隐式转换应启动,但当然不会,即使显式调用转换也没问题。

link @slouc给出了答案,即Scala编译器在进行隐式解析时以特殊方式处理Nothing,因为Nothing是类型的默认下界进行类型推断。

现在为什么Nothing不能在隐式解决方案中考虑到它?那么关于Nothing的棘手问题是它是一切的子类型。这意味着如果Scala在任何时候推断类型为Nothing,则每个隐式转换都会立即生效。这可能会隐藏类型错误(您永远不应该有Nothing的实例,但是当Nothing成为Int时......那么谁呢?)。 (注意我会喜欢那些真正攻击编译器的人跳入并确认/否认/详细说明这一点)

答案 1 :(得分:1)

编辑:可能这个答案不正确。但我在这里保守,以示我是如何尝试调查此问题的。对我而言,它看起来像是编译器中的一个错误。

答案是Array[T <: AnyRef]存在的隐式转换 字符串为AnyRefNothing不是AnyRef

你怎么能自己发现这个?

在IntelliJ中,您可以在isEmpty下看到灰色下划线 enter image description here

这意味着方法isEmpty不是Array的方法,而是隐式(在类中具有隐式转换的类的方法)。

现在,要发现隐式转化,只需点击ctrl+q enter image description here

所以当你按照它时,你会在源代码中找到这一行 -

  implicit def refArrayOps[T <: AnyRef](xs: Array[T]): ArrayOps[T]    = new ArrayOps.ofRef[T](xs)

这解释了当T扩展AnyRef

时隐式转换在Array [T]上

回到我们的案例 - String <: AnyRef,但这不适用于Nothing