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

发布于 2024-08-25 05:14:36 字数 122 浏览 4 评论 0原文

假设我有一个未初始化的 MyObject 实例:

var a:MyObject = null

这是将其初始化为 null 的正确方法吗?

Let's say I have a MyObject instance which is not initialized:

var a:MyObject = null

is this the proper way to initialize it to null?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

屌丝范 2024-09-01 05:14:36

替代方案

使用 null 作为最后的手段。正如已经提到的,Option 取代了 null 的大部分用法。如果您使用 null 来实现字段的延迟初始化并进行一些昂贵的计算,则应该使用 lazy val

规范初始化为 null

也就是说,Scala 确实支持 null。我个人将它与 Spring 依赖注入结合使用。

您的代码完全有效。不过,我建议您使用 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

高级

使用 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 的子类型而不是 NotNull 的子类型不完全

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

Alternatives

Use null as a last resort. As already mentioned, Option replaces most usages of null. If you using null to implement deferred initialisation of a field with some expensive calculation, you should use a lazy val.

Canonical initialisation to null

That said, Scala does support null. I personally use it in combination with Spring Dependency Injection.

Your code is perfectly valid. However, I suggest that you use var t: T = _ to initialize t to it's default value. If T is a primitive, you get the default specific to the type. Otherwise you get null.

Not only is this more concise, but it is necessary when you don't know in advance what T will be:

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= null is a compile error if T is unbounded:

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 T is nullable -- a subtype of AnyRef not a subtype of NotNull This isn't fully baked, even in Scala 2.8, so just consider it a curiousity for now.

scala> class A[T](implicit ev: Null <:< T) { var t: T = null }           
defined class A
厌倦 2024-09-01 05:14:36

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

var a = None : Option[MyObject]

当您想要设置它时:

a = Some(foo)

当您想要从中读取内容时,测试 None:

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

The canonical answer is don't use null. Instead, use an option type:

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:

a match {
  case None => Console.println("not here")
  case Some(value) => Console.println("got: "+value)
}
情栀口红 2024-09-01 05:14:36

正如 David 和 Retronym 已经提到的,在大多数情况下使用 Option 是个好主意,因为 Option 使您更明显地必须处理无结果的情况。但是,返回 Some(x) 需要创建对象,并且调用 .get.getOrElse 可能比 if 语句更昂贵。因此,在高性能代码中,使用 Option 并不总是最好的策略(特别是在集合查找代码中,您可能会多次查找某个值,并且不希望相应地创建很多对象) 。话又说回来,如果您正在执行类似返回整个网页(可能不存在)的文本之类的操作,则没有理由使用Option。

另外,只是为了用 null 来补充一下关于泛型的反义词,如果你真的意味着它应该是 null ,你可以以一种完全成熟的方式来做到这一点:

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

这适用于2.7 和 2.8。它比 <:< 方法不太通用,因为它不遵守 NotNull AFAIK,但它在其他方面完全按照您希望的方式执行。

As David and retronym have already mentioned, it's a good idea to use Option in most cases, as Option makes it more obvious that you have to handle a no-result situation. However, returning Some(x) requires an object creation, and calling .get or .getOrElse can be more expensive than an if-statement. Thus, in high-performance code, using Option is 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 not to use 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:

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 NotNull AFAIK, but it otherwise does exactly what you'd hope it would do.

冬天旳寂寞 2024-09-01 05:14:36

我遇到了这个问题,因为 scalastyle 告诉我在使用 null 初始化测试中的对象时不要使用 null。

我的解决方案无需更改任何满足 scalastyle 的类型:

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

I came across this question since scalastyle told me to not use null when initialising an object within my test with null.

My solution without changing any type that satisfied scalastyle:

var a: MyObject = (None: Option[MyObject]).orNull
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文