为什么我无法声明用null初始化的参数化类型的变量?

时间:2013-10-17 19:06:25

标签: scala generics traits

为什么这不起作用?

trait testtrait[T] {
  var ob:T = null
}

然后scalac testtrait.scala产生

testtrait.scala:2: error: type mismatch;
 found   : Null(null)
 required: T
  var ob:T = null
             ^
one error found

我正在使用Scala 2.9

3 个答案:

答案 0 :(得分:5)

我不能确切地说为什么,但是下划线的概念(这是类型的默认值的快捷方式,对象是空的)将正常工作:

trait testtrait[T] {
  var ob:T = _
}

更多可怕的解决方法是asInstanceOf施放,但我发现下划线更好的选择。

trait testtrait[T] {
  var ob:T = null.asInstanceOf[T]
}

答案 1 :(得分:5)

nullNull类型的值,但任何类型都没有Null作为子类型,只有AnyRef - 派生的类型(当然除了Nothing。假设您执行了类似

的操作
object SomeObj extends testtrait[Int]

SomeObj.ob应该等于什么?它是Int,因此它没有null作为可能的值。

正如在其他答案中所说,您应该使用下划线语法来设置类型的默认值。

答案 2 :(得分:2)

所有类型的底部类型是Nothing。这意味着任何类型T(不受其他约束)可以是Nothing,而null不是Nothing(事实上,没有值)。

因此,为了能够分配null,您必须将其编写为[T >: Null]TNull的超类型。

另一方面,您可以使用var ob: T = _将其初始化为默认值。但是,请注意,对于任何AnyValT将被装箱并分配null而非0,这可能会导致意外结果。