假设我有一个MyObject未初始化的实例:
var a:MyObject = null
Run Code Online (Sandbox Code Playgroud)
这是将它初始化为null的正确方法吗?
ret*_*nym 62
使用null作为最后的手段.如前所述,Option替换大多数null的用法.如果您使用null一些昂贵的计算来实现字段的延迟初始化,则应使用a lazy val.
也就是说,Scala确实支持null.我个人将它与Spring Dependency Injection结合使用.
您的代码完全有效.但是,我建议您使用var t: T = _初始化t为默认值.如果T是基元,则获取特定于该类型的默认值.否则你会得到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
Run Code Online (Sandbox Code Playgroud)
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 }
Run Code Online (Sandbox Code Playgroud)
你可以添加一个隐式参数作为可以T为空的证据- AnyRef不是子类型的子类型即使在Scala 2.8中NotNull也没有完全烘焙,所以现在只考虑它是一个好奇心.
scala> class A[T](implicit ev: Null <:< T) { var t: T = null }
defined class A
Run Code Online (Sandbox Code Playgroud)
Dav*_*haw 32
规范的答案是不要使用null.而是使用选项类型:
var a = None : Option[MyObject]
Run Code Online (Sandbox Code Playgroud)
如果要设置它:
a = Some(foo)
Run Code Online (Sandbox Code Playgroud)
当你想从中读取时,测试无:
a match {
case None => Console.println("not here")
case Some(value) => Console.println("got: "+value)
}
Run Code Online (Sandbox Code Playgroud)
正如David和反义词已经提到的那样,Option在大多数情况下使用它是一个好主意,因为Option更明显的是你必须处理无结果的情况.但是,返回Some(x)需要创建对象,并且调用.get或者.getOrElse比if语句更昂贵.因此,在高性能代码中,使用Option并不总是最好的策略(特别是在集合查找代码中,您可能会多次查找值并且不需要相应的对象创建).然后,如果你正在做一些事情,比如返回整个网页的文本(可能不存在),就没有理由不使用Option.
另外,只是为了在泛型中添加反义词的null含义,你可以用一种完全出炉的方式做到这一点,如果你真的应该这样做null:
class A[T >: Null] { var t: T = null }
Run Code Online (Sandbox Code Playgroud)
这适用于2.7和2.8.它比<:<方法稍微不那么通用,因为它不遵守NotNullAFAIK,但它完全按照你希望的那样做.