import scala.util.Try
val m = Map("a" -> "false", "b" -> "true")
Try(m.get("a").map(_.toBoolean)).getOrElse(false)
我想要返回的是布尔值,而不是Try或Option,但目前Try正在阻碍。
答案 0 :(得分:3)
如果字符串成功解析为真的布尔值,看起来您有兴趣返回true
,否则返回false(例如“True”= true
和“true”= {{1} },但“false”和“abc”都是true
)。
以下是如何使用您的模型:
false
作为良好实践,我建议使用异常来避免控制流。 val m = Map("a" -> "false", "b" -> "true")
val aBool = Try(m.get("a").map(_.toBoolean).getOrElse(false)).getOrElse(false)
monad很好写,但是比稍微更丑的替代品要糟糕得多。看一下this performance chart - 如果你遇到过无法成功解析的值,你就会在脚下拍摄你的表演。
使用一些字符串比较可以使这个工作流程的速度提高几个星期。
Try
答案 1 :(得分:0)
您尝试做的事情可能会(至少)以两种不同的方式失败:
m
没有密钥"a"
(因为Map
类型不会对"a"
处定义的事实进行编码)m
定义"a"
,则无法确定其值是否可以有意义地转换为布尔值的字符串(因为类型String
不对此转换进行编码纯粹的方式)因此,在_.toBoolean
块中包含对Try
的调用,并在地图上使用get
方法是一个非常好的主意,就像您一样。但是,您需要指定对失败案例执行的操作。
在问题中,您使用了getOrElse
块上的Try
,以便从String
转换为Boolean
的错误中恢复。但是,您尚未处理其他失败的可能性,因此Try
块中的内容为Option[Boolean]
,您无法使用false
作为默认值。
如果根本没有恢复,那么
Try(m.get("a").map(_.toBoolean)): Try[Option[Boolean]]
然后,您可以使用.getOrElse(<default-value>)
两次(一次用于Try
,一次用于Option
),以获得Boolean
类型的值。
您还可以考虑Try
块捕获所有错误,而不是确保在m
定义"a"
(但是,我不鼓励这样做,因为它不是一种非常实用的方式来做事情):
Try(m("a").toBoolean).getOrElse(false)
您还可以考虑只有toBoolean
调用必须包含在Try
中,因为其他一切都非常纯粹。此外,您知道此方法只有一种失败方法,因此您可以将Try
转换为Option
:
m.get("a").map(s => Try(s.toBoolean).toOption): Option[Option[Boolean]]
或者,如果您不想区分这两个错误:
m.get("a").flatMap(s => Try(s.toBoolean).toOption): Option[Boolean]
在每种情况下,一个或两个getOrElse
将提取所需的值,同时确保不会抛出任何错误。