Option[T] 类的意义何在? [英] What is the point of the class Option[T]?

查看:38
本文介绍了Option[T] 类的意义何在?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法理解 Scala 中 Option[T] 类的意义.我的意思是,我看不到 None 优于 null 的任何优势.

I am not able to understand the point of Option[T] class in Scala. I mean, I am not able to see any advanages of None over null.

例如,考虑代码:

object Main{
  class Person(name: String, var age: int){
    def display = println(name+" "+age)
  }

  def getPerson1: Person = {
    // returns a Person instance or null
  }

  def getPerson2: Option[Person] = {
    // returns either Some[Person] or None
  }

  def main(argv: Array[String]): Unit = {
    val p = getPerson1
    if (p!=null) p.display

    getPerson2 match{
      case Some(person) => person.display
      case None => /* Do nothing */
    }
  }
}

现在假设,方法 getPerson1 返回 null,然后在 maindisplay> 肯定会因 NPE 而失败.同样,如果 getPerson2 返回 Nonedisplay 调用将再次失败并出现一些类似的错误.

Now suppose, the method getPerson1 returns null, then the call made to display on first line of main is bound to fail with NPE. Similarly if getPerson2 returns None, the display call will again fail with some similar error.

如果是这样,那么为什么 Scala 通过引入新的值包装器(Option[T])而不是遵循 Java 中使用的简单方法来使事情复杂化?

If so, then why does Scala complicate things by introducing a new value wrapper (Option[T]) instead of following a simple approach used in Java?

更新:

我已按照 @Mitch 的建议编辑了我的代码.我仍然看不到 Option[T] 的任何特殊优势.在这两种情况下,我都必须测试异常的 nullNone.:(

I have edited my code as per @Mitch's suggestion. I am still not able to see any particular advantage of Option[T]. I have to test for the exceptional null or None in both cases. :(

如果我从 @Michael 的回复 中正确理解,这是 Option[T] 是它明确告诉程序员这个方法可以返回 None 吗?这是这个设计选择背后的唯一原因吗?

If I have understood correctly from @Michael's reply, is the only advantage of Option[T] is that it explicitly tells the programmer that this method could return None? Is this the only reason behind this design choice?

推荐答案

如果你强迫自己永远不要使用 get 你会更好地理解 Option>.那是因为 get 相当于好的,送我回空地".

You'll get the point of Option better if you force yourself to never, ever, use get. That's because get is the equivalent of "ok, send me back to null-land".

所以,以你的例子为例.如果不使用 get,您将如何调用 display?以下是一些替代方案:

So, take that example of yours. How would you call display without using get? Here are some alternatives:

getPerson2 foreach (_.display)
for (person <- getPerson2) person.display
getPerson2 match {
  case Some(person) => person.display
  case _ =>
}
getPerson2.getOrElse(Person("Unknown", 0)).display

这些替代方法都不会让您在不存在的东西上调用 display.

None of this alternatives will let you call display on something that does not exist.

至于为什么 get 存在,Scala 没有告诉你应该如何编写代码.它可能会轻轻地刺激你,但如果你想回到没有安全网的地方,这是你的选择.

As for why get exists, Scala doesn't tell you how your code should be written. It may gently prod you, but if you want to fall back to no safety net, it's your choice.

你把它钉在这里:

是 Option[T] 的唯一优势是它明确地告诉程序员认为这种方法可以返回无?

is the only advantage of Option[T] is that it explicitly tells the programmer that this method could return None?

唯一"除外.但让我以另一种方式重申:Option[T] 相对于 Tmain 优势是类型安全.它确保您不会向可能不存在的对象发送 T 方法,因为编译器不会让您这样做.

Except for the "only". But let me restate that in another way: the main advantage of Option[T] over T is type safety. It ensures you won't be sending a T method to an object that may not exist, as the compiler won't let you.

你说你必须在这两种情况下测试可空性,但如果你忘记——或者不知道——你必须检查空值,编译器会告诉你吗?或者您的用户会吗?

You said you have to test for nullability in both cases, but if you forget -- or don't know -- you have to check for null, will the compiler tell you? Or will your users?

当然,由于它与 Java 的互操作性,Scala 允许空值,就像 Java 一样.因此,如果您使用 Java 库,如果您使用写得不好的 Scala 库,或者如果您使用写得不好的个人 Scala 库,您仍然需要处理空指针.

Of course, because of its interoperability with Java, Scala allows nulls just as Java does. So if you use Java libraries, if you use badly written Scala libraries, or if you use badly written personal Scala libraries, you'll still have to deal with null pointers.

我能想到的Option的另外两个重要优点是:

Other two important advantages of Option I can think of are:

  • 文档:方法类型签名会告诉你一个对象是否总是被返回.

  • Documentation: a method type signature will tell you whether an object is always returned or not.

Monadic 可组合性.

Monadic composability.

后者需要更长的时间才能完全理解,并且不太适合简单的示例,因为它仅在复杂代码上显示其优势.所以,我将在下面举一个例子,但我很清楚,除了已经得到它的人之外,它几乎没有任何意义.

The latter one takes much longer to fully appreciate, and it's not well suited to simple examples, as it only shows its strength on complex code. So, I'll give an example below, but I'm well aware it will hardly mean anything except for the people who get it already.

for {
  person <- getUsers
  email <- person.getEmail // Assuming getEmail returns Option[String]
} yield (person, email)

这篇关于Option[T] 类的意义何在?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆