2013-03-20 106 views
3

在python中,你可以避免{012} {} {{} {{} {}樣板{with(見What is the python keyword "with" used for?)。我記得在Scala中看到了另一個選擇,但我再也找不到它了。Scala替代蟒蛇``與`

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

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

它是內置到2.10,或者我需要爲它單獨庫:

它沿着線去?

+5

這樣做的最廣爲人知的庫https://github.com/jsuereth/scala-arm,也沒有,據我所知沒有按階」 t開箱即用提供此功能 – 2013-03-20 08:58:34

回答

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 
+0

我找到了一個類似的解決方案,但我認爲應該有一些已經存在的東西。 scala-arm似乎是一種令人信服的替代方案,可以自己滾動。 – iwein 2013-03-20 09:18:40

+1

@iwein - 如果你想要的比你所要求的更多,scala-arm確實很有吸引力。僅此而已,添加依賴項而不是三行代碼是一種奇怪的強制。 – 2013-03-20 09:49:36

+0

點了。你用scala-arm獲得的語法可以說比你用TidyUpAnything獲得的語法更好。我有點滑稽,在一般情況下添加隱含條件... – iwein 2013-03-21 06:43:45