这是在Scala中初始化空引用的正确方法吗?

比方说,我有一个未初始化的MyObject实例:

 var a:MyObject = null 

这是正确的方法来初始化为空?

备择scheme

使用null作为最后的手段。 如前所述, Option取代了大多数的null用法。 如果你使用null来实现延迟初始化一个昂贵的计算的字段,你应该使用一个lazy val

规范初始化为null

也就是说,Scala支持null 。 我个人将它与Springdependency injection结合使用。

你的代码是完全有效的。 不过,我build议你使用var t: T = _t初始化为默认值。 如果T是一个原始types,你会得到特定types的默认值。 否则,你会得到null

这不仅更简洁,而且当你事先不知道T是什么时,

 scala> class A[T] { var t: T = _ } defined class A scala> new A[String].t res0: String = null scala> new A[Object].t res1: java.lang.Object = null scala> new A[Int].t res2: Int = 0 scala> new A[Byte].t res3: Byte = 0 scala> new A[Boolean].t res4: Boolean = false scala> new A[Any].t res5: Any = null 

高级

使用var t: T= null是一个编译错误,如果T是无界的:

 scala> class A[T] { var t: T = null } <console>:5: error: type mismatch; found : Null(null) required: T class A[T] { var t: T = null } 

你可以添加一个隐式参数作为T是可以为空的证据 – AnyRef的子types不是AnyRef的子types即使在Scala 2.8中,它也没有被完全烘焙 ,所以现在就认为它是一个好奇。

 scala> class A[T](implicit ev: Null <:< T) { var t: T = null } defined class A 

规范的答案是不要使用null 。 相反,使用选项types:

 var a = None : Option[MyObject] 

当你想要设置它:

 a = Some(foo) 

而当你想从中读取,testing无:

 a match { case None => Console.println("not here") case Some(value) => Console.println("got: "+value) } 

正如David和retrony已经提到的那样,在大多数情况下使用Option是一个好主意,因为Option更明显的是你必须处理一个没有结果的情况。 但是,返回Some(x)需要创build对象,调用.get.getOrElse可能比if语句更昂贵。 因此,在高性能的代码中,使用Option并不总是最好的策略(尤其是在收集查找代码中,您可能会查找很多次的值,并且不希望相应地创build多个对象)。 然后再一次,如果你正在做一些像返回整个网页(这可能不存在)的文本,没有理由使用选项。

另外,如果你真的认为它应该是null ,那么只需要在generics上添加null就可以完全做到这一点:

 class A[T >: Null] { var t: T = null } 

这在2.7和2.8的作品。 它比<:<方法稍微less一些,因为它不遵从NotNull AFAIK,但是否则它就是你所期望的。

我遇到过这个问题,因为Scalastyle告诉我在初始化testing中的一个对象时不要使用null

我的解决scheme不改变任何满足scalastyle的types:

 var a: MyObject = (None: Option[MyObject]).orNull