这是在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