对于这个用例来说,贷款模式更为常见,但由于 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 不代表巨魔。)