gpt4 book ai didi

另一个 Option 对象内的 Scala Option 对象

转载 作者:行者123 更新时间:2023-12-04 04:47:11 29 4
gpt4 key购买 nike

我有一个模型,它有一些 Option 字段,其中包含另一个 Option 字段。例如:

case class First(second: Option[Second], name: Option[String])
case class Second(third: Option[Third], title: Option[String])
case class Third(numberOfSmth: Option[Int])

我从外部 JSON 接收这些数据,有时这些数据可能包含空值,这就是这种模型设计的原因。

所以问题是:获得最深场的最佳方法是什么?
First.get.second.get.third.get.numberOfSmth.get

上面的方法看起来非常难看,如果其中一个对象为 None,则可能会导致异常。我正在寻找 Scalaz lib,但没有想出更好的方法来做到这一点。

有任何想法吗?
提前致谢。

最佳答案

解决方法是使用Option.mapOption.flatMap :

First.flatMap(_.second.flatMap(_.third.map(_.numberOfSmth)))

或等效的(请参阅本答案末尾的 更新 ):
First flatMap(_.second) flatMap(_.third) map(_.numberOfSmth)

这将返回 Option[Int] (前提是 numberOfSmth 返回 Int )。如果调用链中的任何选项是 None ,结果将是 None , 否则为 Some(count)哪里 countnumberOfSmth 返回的值.

当然,这会很快变得丑陋。出于这个原因,scala 支持将理解作为一种语法糖。以上可以改写为:
for { 
first <- First
second <- first .second
third <- second.third
} third.numberOfSmth

这可以说更好(特别是如果您还不习惯在任何地方看到 map/ flatMap,使用 scala 一段时间后肯定会出现这种情况),并在引擎盖下生成完全相同的代码。

有关更多背景信息,您可以查看另一个问题: What is Scala's yield?

更新 :
感谢 Ben James 指出 flatMap 是关联的。换句话说 x flatMap(y flatMap z)))x flatMap y flatMap z 相同.虽然后者通常不会更短,但它具有避免任何嵌套的优点,这更容易遵循。

这是 REPL 中的一些说明(4 种样式是等效的,前两种使用 flatMap 嵌套,其他两种使用 flatMap 的扁平链):
scala> val l = Some(1,Some(2,Some(3,"aze")))
l: Some[(Int, Some[(Int, Some[(Int, String)])])] = Some((1,Some((2,Some((3,aze))))))
scala> l.flatMap(_._2.flatMap(_._2.map(_._2)))
res22: Option[String] = Some(aze)
scala> l flatMap(_._2 flatMap(_._2 map(_._2)))
res23: Option[String] = Some(aze)
scala> l flatMap(_._2) flatMap(_._2) map(_._2)
res24: Option[String] = Some(aze)
scala> l.flatMap(_._2).flatMap(_._2).map(_._2)
res25: Option[String] = Some(aze)

关于另一个 Option 对象内的 Scala Option 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15111565/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com