2016-11-14 55 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將提取所需的值,同時確保不會拋出錯誤。