2016-11-14 77 views
1
import scala.util.Try 

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

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

我想返回的是一个布尔值,而不是一次或一个选项,但目前正在尝试的方式获得。安全解析字符串到布尔

+1

您不能“安全地”将任意字符串解析为任何内容。请更好地描述你的问题。 “Try”有什么问题? – laughedelic

+5

这可以简化为Try(m(“a”)。toBoolean).getOrElse(false)'。如果没有'Option',你会安全地得到'true'或'false'。 – jwvh

+1

出于好奇,为什么不简单地定义'm'有类型:'Map [String,Boolean]',即'Map(“a” - > false,“b” - > true)'? –

回答

2

它看起来像你有兴趣返回true如果字符串成功解析到一个真正的布尔值,否则为假(如“真” = true和“真” = true,但“假”和“ABC”是均为false)。

这里是如何做到这一点与模型:

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

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

作为很好的做法,我会建议避免使用异常的控制流。monad写起来很好,但比稍微丑陋的选择表现要差得多。看看this performance chart - 如果你遇到过不能成功解析的值,那么你就是在脚下拍摄你的表演。

使用一些字符串比较将使此工作流程的数量级更快。

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

val aBool = m.get("a").exists(_.toLowerCase() == "true") 
0

你试图做可能失败了怎么办(至少)两种不同的方式:

  • 地图m没有一个关键"a"(因为类型Map不编码的事实定义在"a"
  • 如果m定义在"a"你不能确定它的值是一个可以有意义地转换为布尔值的字符串(因为类型String不编码这个在一个纯粹的方式翻译)

因此,将呼叫换到_.toBooleanTry块,并使用地图上的get方法,因为你做了一个非常好的主意。但是,您需要指定对失败的案例执行的操作。

在问题中,您在Try块上使用了getOrElse,从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包裹,因为一切是相当纯正。而且,你知道,这种方法只有一个办法失败了,所以你可以转换TryOption

m.get("a").map(s => Try(s.toBoolean).toOption): Option[Option[Boolean]]

或者,如果你不想让两个错误之间的区别:

m.get("a").flatMap(s => Try(s.toBoolean).toOption): Option[Boolean]

在每种情况下,一个或两个getOrElse将提取所需的值,同时确保不会抛出错误。