代码之家  ›  专栏  ›  技术社区  ›  Gibbs

scala类型推断不作为函数args用于数组

  •  1
  • Gibbs  · 技术社区  · 7 年前
    var arr = new Array(3)
    
    returns type of Nothing.
    
    arr(0)="Hi"
    

    抛出错误。我知道没有什么东西不是一种超类型的弦。

    为什么它不返回像Java那样的对象,它对于所有的实例都是超级类。以便我可以在其中分配任何类型的值。

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

    3 回复  |  直到 7 年前
        1
  •  1
  •   Alexey Romanov    7 年前

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

    在这种情况下:数组构造函数需要一个类型参数,即它实际上是 new Array[A?](3) 为了一些未知的 A? . 编译器对 A? 它可以是任何东西(它不能使用来自 arr(0)="Hi" 下面将添加一个约束)。和 Array 是不变的。在这种情况下,规则说编译器应该选择满足约束的最小类型;这是 Nothing ,因为每种类型都满足(缺少)约束 没有什么 是所有类型中的最小类型。

    您可以通过提供预期的类型来解决此问题

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

    或指定类型参数

    val arr = new Array[String](3)
    
        2
  •  0
  •   Norwæ    7 年前

    您没有指定要创建的数组类型。这就让编译器计算出类型。

    编译器只有两个选项: Any Nothing . 它尝试选择满足指定约束的最特定类型。自从 没有什么 任何 , 没有什么 已选定。解决这个问题很简单。

    注意,即使 java.lang.Object 任何 -毕竟, 任何 甚至可能是原始的 Int .

        3
  •  0
  •   Jatin    7 年前

    对于您提到的示例,当涉及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$[] arr = new Nothing$[3];
    arr[0] = "hi"; //compile time error
    

    This 更深入地了解变化。


    如果你的问题是:

    var arr = new Array(3) ,为什么是 ARR 类型 数组[无] 而不是 Array[Any] ?

    因为编译器需要推断出最好的类型。它通过遵循 LUB (Least Upper Bound) 战略。 没有什么 是本例中最小的上界。