3

在 python 中,你可以避免 try {} catch {} finally {} 样板 with with(参见What is the python keyword "with" used for?)。我记得在 Scala 中看到了替代方案,但我再也找不到了。

它遵循以下原则:

def using[O](r: {def close()})(doit: () => O): O = try {
  doit()
} finally {
  r.close
}

using(myWriter){() => myWriter.println("something or another")}

它是内置在 2.10 中的,还是我需要一个单独的库?

4

1 回答 1

6

自己制作几乎涵盖所有用例(这里使用 2.10)几乎是微不足道的:

implicit class TidyUpAnything[A](val a: A) extends AnyVal {
  def tidily[Z](g: A=>Any)(f: A=>Z) = try { f(a) } finally { g(a) }
}

如果您希望通过异常,请按原样使用:

scala> Option(null: String).tidily(println){_.get}   // Should print None
None
java.util.NoSuchElementException: None.get
    at scala.None$.get(Option.scala:313)
    ...

如果要处理异常,请将其与scala.util.Try结合使用:

scala> import scala.util._
scala> Try( Option(null: String).tidily(println){ _.get } )
None
res1: scala.util.Try[String] = Failure(java.util.NoSuchElementException: None.get)

通常你会做类似的g东西_.close,但你可以用它做任意资源清理。例如,在这里,每当我们完成时,我们都会后退一个计数器:

var i = 0
val a = Array(1,2)
a.tidily(_ => i -= 1){ _.foreach(_ => i += 1) }
scala> i
res2: Int = 1
于 2013-03-20T09:05:26.710 回答