Scala - 类型推断不适用于Arrays作为函数args

时间:2018-05-30 09:40:24

标签: scala

var arr = new Array(3)

returns type of Nothing.

arr(0)="Hi"

抛出错误。我知道Nothing不是超类型的String。

为什么它不返回像Object这样的java,它是所有实例的超类。这样我就可以在其中分配任何类型的值。

我在这里误解了类型推断吗?为什么会这样?是以这种方式有目的地实施的吗?

注意:我广泛使用Java。

3 个答案:

答案 0 :(得分:1)

类型推断的行为在https://www.scala-lang.org/files/archive/spec/2.12/06-expressions.html#local-type-inference中指定。

在这种情况下:数组构造函数需要一个类型参数,即对于某些未知ChromeDriverService.CHROME_DRIVER_EXE_PROPERTY,它实际上是new Array[A?](3)。编译器根本不对A?有任何约束:它可以是任何东西(它不能使用下面A?的信息,这会增加约束)。 arr(0)="Hi"是不变的。在这种情况下,规则说编译器应该选择满足约束的最小类型;那个Array,因为每种类型都满足(缺少)约束,而Nothing是所有类型的最小类型。

您可以通过提供预期类型

来解决此问题
Nothing

或指定类型参数

val arr: Array[String] = new Array(3)

答案 1 :(得分:0)

您没有指定要创建的阵列类型。这使编译器无法确定类型。

编译器只有两个选项:AnyNothing。它会尝试选择满足您指定约束的最具体类型。由于NothingAny更具体,因此会选择Nothing。解决这个问题很简单。

请注意,即使java.lang.ObjectAny更具体 - 毕竟,Any甚至可能是Int这样的原语。

答案 2 :(得分:0)

对于您提到的示例,Scala和Java的行为类似。

scala> var arr = new Array(3)
arr: Array[Nothing] = Array(null, null, null)

arr的类型为Array[Nothing]。因此,对arr的任何读取或写入都应为Nothing类型。因此,下面是编译时错误:

arr(0) = "Hi"
Expression of type String doesn't conform to expected type Nothing

并且:

var t: Nothing = arr(0)

t必须严格为Nothing或其子类型。这与Java中的行为相同:

Nothing$[] arr = new Nothing$[3];
arr[0] = "hi"; //compile time error

This可以更深入地了解差异。

如果你的问题是:

var arr = new Array(3)中,为什么arr类型为Array[Nothing]而不是Array[Any]

因为编译器需要推断出最佳类型。它遵循LUB (Least Upper Bound)策略来实现。在这种情况下,Nothing是最小上限。