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)
我希望这可以为选择如何使生活变得更轻松提供一些启示。
TA贡献1812条经验 获得超5个赞
区别是微妙的。请记住,要真正成为一个函数,它必须返回一个值-从这个意义上讲,null并不是真正的“正常返回值”,更多的是底部类型 /无。
但是,从实际意义上讲,当调用有选择地返回某些内容的函数时,您会这样做:
getPerson2 match {
case Some(person) => //handle a person
case None => //handle nothing
}
当然,您可以使用null做类似的事情-但这使调用的语义因其getPerson2返回的事实而变得显而易见Option[Person](这是一件很实际的事情,除了依靠某人阅读文档并获得NPE的原因是,他们不读文档doc)。
我将尝试找出一个能给出比我更严格答案的功能程序员。
添加回答
举报