贷款模式在这个用例中更为常见,但由于 Stack Overflow 上发生任何事情,您可以使用 构建您要查找的表达式Try
。
Try
作为一个方便的工具,值得更多的曝光。
scala> import util._
import util._
scala> import io._
import io._
尝试打开文件——
scala> def f =
| Try (Source.fromFile("foo.text")) map { in =>
然后用它做一些事情,将结果包装在一个带有 i/o 源的元组中——注意,当你在 for-comprehension 中定义值时,它就是这样做的——
| (in, Try(in.getLines.mkString("/")))
| } flatMap {
然后关闭源并产生计算结果 -
| case (in, res) =>
| in.close()
| res
| }
f: scala.util.Try[String]
未注释:
scala> def f =
| Try (Source.fromFile("foo.text")) map { in =>
| (in, Try(in.getLines.mkString("/")))
| } flatMap {
| case (in, res) =>
| in.close()
| res
| }
f: scala.util.Try[String]
scala> f
res1: scala.util.Try[String] = Failure(java.io.FileNotFoundException: foo.text (No such file or directory))
用一些经典的幽默文本创建测试文件,然后再试一次:
scala> f
res2: scala.util.Try[String] = Success(Now is the time/for all good dogs/to lie.)
您可以将其粉饰为便于理解,但请注意额外的扁平化,因为您从产量中获得了地图而不是 flatMap:
scala> def g = (for {
| in <- Try (Source.fromFile("foo.text"))
| res = Try(in.getLines.mkString("/"))
| } yield {
| in.close()
| res
| }).flatten
g: scala.util.Try[String]
scala> g
res2: scala.util.Try[String] = Success(Now is the time/for all good dogs/to lie.)
如果关闭失败,我们想失败怎么办?
我不想再在 REPL 中输入所有这些东西!
scala> :hi // :history
[snip]
2490 def g = (for {
2491 in <- Try (Source.fromFile("foo.text"))
2492 res = Try(in.getLines.mkString("/"))
2493 } yield {
2494 in.close()
2495 res
2496 }).flatten
2497 :hi
scala> :edit 2490+7 // or just :edit 2490-
+import util._
+import io._
+def g = (for {
+ in <- Try (Source.fromFile("foo.text"))
+ res = Try(in.getLines.mkString("/"))
+} yield {
+ val ok = Try(in.close())
+ res transform (s => ok map (_ => s), new Failure(_))
+}).flatten
+
import util._
import io._
g: scala.util.Try[String]
transform
表示如果计算成功,如果关闭的结果是失败,则将该成功转换为ok
失败;并且在计算失败时,保留该失败,尽管有些人更喜欢将他们的失败加起来。
你不知道 try/catch 是 1990 年代。</droll>(droll 并不意味着巨魔。)