这是在 Scala 中初始化空引用的正确方法吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2440134/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is this the proper way to initialize null references in Scala?
提问by Geo
Let's say I have a MyObjectinstance which is not initialized:
假设我有一个MyObject未初始化的实例:
var a:MyObject = null
is this the proper way to initialize it to null?
这是将其初始化为空的正确方法吗?
回答by retronym
Alternatives
备择方案
Use nullas a last resort. As already mentioned, Optionreplaces most usages of null. If you using nullto implement deferred initialisation of a field with some expensive calculation, you should use a lazy val.
使用null作为最后的手段。如前所述,Option替换 null 的大多数用法。如果您使用null一些昂贵的计算来实现字段的延迟初始化,则应该使用lazy val.
Canonical initialisation to null
规范初始化为空
That said, Scala does support null. I personally use it in combination with Spring Dependency Injection.
也就是说,Scala 确实支持null. 我个人将它与 Spring 依赖注入结合使用。
Your code is perfectly valid. However, I suggest that you use var t: T = _to initialize tto it's default value. If Tis a primitive, you get the default specific to the type. Otherwise you get null.
您的代码完全有效。但是,我建议您使用var t: T = _初始化t为其默认值。如果T是原始类型,您将获得特定于该类型的默认值。否则你得到null.
Not only is this more concise, but it is necessary when you don't know in advance what Twill be:
这不仅更简洁,而且在您事先不知道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
Advanced
先进的
Using var t: T= nullis a compile error if T is unbounded:
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 }
You can add an implicit parameter as evidence that Tis nullable -- a subtype of AnyRefnot a subtype of NotNullThis isn't fully baked, even in Scala 2.8, so just consider it a curiousity for now.
您可以添加一个隐式参数作为可以T为空的证据——一个AnyRef不是NotNullThis的子类型的子类型还没有完全烘焙,即使在 Scala 2.8 中,所以现在只考虑它的好奇。
scala> class A[T](implicit ev: Null <:< T) { var t: T = null }
defined class A
回答by David Crawshaw
The canonical answer is don't use null. Instead, use an option type:
规范的答案是不要使用 null。相反,使用选项类型:
var a = None : Option[MyObject]
When you want to set it:
当你想设置它时:
a = Some(foo)
And when you want to read from it, test for None:
当您想从中读取时,请测试 None:
a match {
case None => Console.println("not here")
case Some(value) => Console.println("got: "+value)
}
回答by Rex Kerr
As David and retronym have already mentioned, it's a good idea to use Optionin most cases, as Optionmakes it more obvious that you have to handle a no-result situation. However, returning Some(x)requires an object creation, and calling .getor .getOrElsecan be more expensive than an if-statement. Thus, in high-performance code, using Optionis not always the best strategy (especially in collection-lookup code, where you may look up a value very many times and do not want correspondingly many object creations). Then again, if you're doing something like returning the text of an entire web page (which might not exist), there's no reason notto use Option.
正如 David 和 retronym 已经提到的,Option在大多数情况下使用它是一个好主意,因为Option它更明显地表明您必须处理无结果的情况。但是,返回Some(x)需要创建对象,并且调用.getor.getOrElse可能比 if 语句更昂贵。因此,在高性能代码中,使用Option并不总是最好的策略(特别是在集合查找代码中,您可能会多次查找一个值并且不希望相应地创建很多对象)。再说一次,如果您正在执行诸如返回整个网页的文本(可能不存在)之类的操作,则没有理由不使用 Option。
Also, just to add to retronym's point on generics with null, you can do this in a fully-baked way if you really mean it should be null:
另外,只是为了增加对泛型的retronym点,null如果你真的想这样做,你可以完全烘焙null:
class A[T >: Null] { var t: T = null }
and this works in 2.7 and 2.8. It's a little less general than the <:<method, because it doesn't obey NotNullAFAIK, but it otherwise does exactly what you'd hope it would do.
这适用于 2.7 和 2.8。它比该<:<方法更不通用,因为它不遵守NotNullAFAIK,但在其他方面它完全符合您的希望。
回答by Guenter
I came across this question since scalastyle told me to not use null when initialising an object within my test with null.
我遇到了这个问题,因为 scalastyle 告诉我在使用null.
My solution without changing any type that satisfied scalastyle:
我的解决方案没有改变任何满足 scalastyle 的类型:
var a: MyObject = (None: Option[MyObject]).orNull

