选项[T]的要点是什么? [英] What is the point of the class Option[T]?

查看:109
本文介绍了选项[T]的要点是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法理解Scala中的 Option [T] 类。我的意思是,我无法看到 None 超过 null 的任何优势。



例如,考虑下面的代码:

  object Main {
class Person(name: String,var age:int){
def display = println(name ++ age)
}
$ b $ def getPerson1:Person = {
// //返回a Person实例或null
}

def getPerson2:Option [Person] = {
//返回Some [Person]或None
}

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

getPerson2 match {
case Some(person)=> person.display
case None => / *什么都不做* /
}
}
}

现在假设 getPerson1 方法返回 null ,然后调用显示 main 的第一行上的c $ c>必然会失败,并且 NPE 。同样,如果 getPerson2 返回 None ,则显示调用将再次如果是这样,那么为什么斯卡拉通过引入一个新的值包装( Option [T] )而不是遵循Java中使用的简单方法?



更新:



我按照 @Mitch 的建议编辑了我的代码。我仍然无法看到 Option [T] 的特殊优势。我必须在这两种情况下测试例外的 null None 。 :(b / b)

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

解决方案

您会得到 Option 更好,如果你强迫自己永远不要使用 get 。这是因为 get

所以,以你的例子为例,你将如何调用 display code>不使用获得?以下是一些替代方案:

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

这些选项都不会让你调用显示



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




你钉了它在这里:
$ b


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


除仅外。但让我以另一种方式重申: Option [T] T main c>是类型安全。它确保你不会发送 T 方法给一个可能不存在的对象,因为编译器不会让你。



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

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



Option的另外两个重要优点是:


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

  • 单向可组合性

    >


后者需要更长时间才能充分理解,并且它不适合简单的示例,因为它仅显示其优势复杂的代码。所以,我会在下面举一个例子,但我很清楚,除了那些已经获得它的人以外,它几乎不会有任何意义。

  for {
person< - getUsers
email< - person.getEmail //假设getEmail返回Option [String]
} yield(person,email)


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.

For example, consider the code:

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 */
    }
  }
}

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.

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?

UPDATE:

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. :(

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?

解决方案

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".

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

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

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.


You nailed it here:

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

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?

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.

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 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)

这篇关于选项[T]的要点是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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