安全地将字符串解析为布尔值

时间:2016-11-14 15:19:32

标签: scala

import scala.util.Try

val m = Map("a" -> "false", "b" -> "true")

Try(m.get("a").map(_.toBoolean)).getOrElse(false)

我想要返回的是布尔值,而不是Try或Option,但目前Try正在阻碍。

2 个答案:

答案 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将提取所需的值,同时确保不会抛出任何错误。