为了账号安全,请及时绑定邮箱和手机立即绑定

Option [T]类有什么意义?

Option [T]类有什么意义?

幕布斯7119047 2019-12-18 16:42:50
我无法理解Option[T]Scala 的课程重点。我的意思是,我不能看到任何advanages None了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,那么display对的第一行进行的调用main必然会失败NPE。同样,如果getPerson2return None,则display调用将再次失败,并显示类似错误。如果是这样,那么Scala为什么通过引入新的值包装器(Option[T])而不是遵循Java中使用的简单方法来使事情复杂化?更新:我已经按照@Mitch的建议编辑了代码。我仍然看不到的任何特殊优势Option[T]。我必须测试例外情况null或None两种情况。:(如果我从@Michael的答复中正确理解了Option[T],那么它的唯一好处是它明确告诉程序员该方法可以返回None?这是该设计选择背后的唯一原因吗?
查看完整描述

3 回答

?
肥皂起泡泡

TA贡献1829条经验 获得超6个赞

比较:


val p = getPerson1 // a potentially null Person

val favouriteColour = if (p == null) p.favouriteColour else null

与:


val p = getPerson2 // an Option[Person]

val favouriteColour = p.map(_.favouriteColour)

monadic属性bind在Scala中作为map函数出现,它使我们可以链接对象上的操作而不必担心它们是否为“ null”。


再举一个简单的例子。假设我们要查找某人列表中所有喜欢的颜色。


// list of (potentially null) Persons

for (person <- listOfPeople) yield if (person == null) null else person.favouriteColour


// list of Options[Person]

listOfPeople.map(_.map(_.favouriteColour))

listOfPeople.flatMap(_.map(_.favouriteColour)) // discards all None's

或者,也许我们想找到一个人的父亲的母亲的妹妹的名字:


// with potential nulls

val father = if (person == null) null else person.father

val mother = if (father == null) null else father.mother

val sister = if (mother == null) null else mother.sister


// with options

val fathersMothersSister = getPerson2.flatMap(_.father).flatMap(_.mother).flatMap(_.sister)

我希望这可以为选择如何使生活变得更轻松提供一些启示。


查看完整回答
反对 回复 2019-12-18
?
慕雪6442864

TA贡献1812条经验 获得超5个赞

区别是微妙的。请记住,要真正成为一个函数,它必须返回一个值-从这个意义上讲,null并不是真正的“正常返回值”,更多的是底部类型 /无。


但是,从实际意义上讲,当调用有选择地返回某些内容的函数时,您会这样做:


getPerson2 match {

   case Some(person) => //handle a person

   case None => //handle nothing 

}

当然,您可以使用null做类似的事情-但这使调用的语义因其getPerson2返回的事实而变得显而易见Option[Person](这是一件很实际的事情,除了依靠某人阅读文档并获得NPE的原因是,他们不读文档doc)。


我将尝试找出一个能给出比我更严格答案的功能程序员。


查看完整回答
反对 回复 2019-12-18
  • 3 回答
  • 0 关注
  • 523 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信