3

In python you can avoid try {} catch {} finally {} boilerplate with with (see What is the python keyword "with" used for?). I remember seeing an alternative to that in Scala, but I can't find it anymore.

It goes along the lines of:

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

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

Is it built into 2.10, or do I need a separate library for it?

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ますが、それを使用して任意のリソースのクリーンアップを行うことができます。たとえば、ここでは、終了するたびにカウンターを1つずつ戻します。

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 に答える