【问题标题】:Why I'm not able to declare variable of parameterized type initialized with null?为什么我不能声明用 null 初始化的参数化类型的变量?
【发布时间】:2013-10-17 19:06:25
【问题描述】:

为什么这不起作用?

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

【问题讨论】:

  • 为什么是var 而不是val。通常在您不想要的特征中。你想要一个def
  • @wheaties 不正确。你可能有很好的理由想要一个 val 甚至是 var 在一个 trait 中。

标签: scala generics traits


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案2】:

    nullNull 类型的值,但不是 any 类型具有 Null 作为子类型,只有 AnyRef 派生的值(当然,Nothing 除外) .假设你做了类似的事情

    object SomeObj extends testtrait[Int]
    

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

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

    【讨论】:

    • 但是为什么上限类型参数不起作用?我的意思是testtrait[T <: AnyRef]
    • @om-nom-nom,因为Nothing <: AnyRefNothing 没有nullT >: Null <: AnyRef 应该可以工作。我想我的回答在这方面有点不正确,我会修复它。
    【解决方案3】:

    所有类型的底部类型是Nothing。这意味着任何类型T,不受其他限制,都可以是Nothing,并且null 不是Nothing(实际上,没有值是)。

    所以,为了能够分配null,你必须写成[T >: Null]TNull 的超类型)。

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

    【讨论】:

      猜你喜欢
      • 2013-03-05
      • 2014-04-13
      • 1970-01-01
      • 1970-01-01
      • 2017-06-22
      • 1970-01-01
      • 2015-05-16
      • 2011-05-26
      • 1970-01-01
      相关资源
      最近更新 更多