2011-02-28 60 views
19

有Scala中打開一個資源和應用方法比這種方法(直接從Java tranlsated),使用vals也包括終於等更idomatic方式功能的嘗試和捕捉W /斯卡拉

var is:FileInputStream = null 
try { 
    is = new FileInputStream(in) 
    func(is) 
} catch { 
    case e:IOException => 
    println("Error: could not open file.") 
    println("  -> " + e) 
    exit(1) 
} finally { 
    if(is) is.close() 
} 
+2

你可以嘗試「自動-資源管理」圖書館:https://開頭github上。 com/jsuereth/scala-arm/wiki/basic-usage – Fabian 2011-03-01 09:13:28

+1

您正在尋找稱爲自動資源管理的功能,這是我們可以預見的Java 7中少數功能之一。 – 2011-03-01 16:28:21

回答

18

在Github的Josh Suereth的scala-arm庫中,貸款模式以各種方式實施。

然後,您可以使用一個資源這樣的:

val result = managed(new FileInputStream(in)).map(func(_)).opt 

這將返回func包裹在一個Option結果,並採取關閉輸入流的照顧。

爲了應對可能出現的異常時創建的資源,您可以用scala.util.control.Exception對象結合起來:

import resource._ 
import util.control.Exception.allCatch 

allCatch either { 
    managed(new FileInputStream(in)).map(func(_)).opt 
} match { 
    case Left(exception) => println(exception) 
    case Right(Some(result)) => println(result) 
    case _ => 
} 
13
+1

+1 ;我不知道他們給了這個成語一個名字。 – 2011-03-01 00:37:13

+1

在Scala標準庫中是否有這樣的標準實現,還是應該在util模塊中創建自己的標準? – 2011-03-01 03:00:00

+0

@aharon請參閱下面的評論 - Josh Suereth的ARM庫可以做到這一點。 – 2011-03-01 16:27:28

5

這可能是一種情況下,不希望功能。已經提到的貸款模式僅僅是錯誤處理的衝擊性版本的封裝,但這與函數式編程沒有關係,並且也處理錯誤處理。

如果你真的想要它的功能,你可以做一個error handling monad。出於充分的理由,我提供的鏈接是Haskell特定的文檔,因爲Scala並不支持這種「核心」功能實踐。

我會建議你採取必要的方式,最後使用try catch ...你也可以用錯誤處理來擴展貸款模式,但這意味着如果你想以不同的方式處理錯誤,你必須編寫特殊的函數在某些情況下,或者你將不得不通過一個部分函數來處理錯誤(這不過是你在代碼中的catch塊中已經有的東西)。

+0

有道理。謝謝! – 2011-03-01 02:59:19

+0

我們需要一個monad嗎?在Haskell中,你有'bracket'函數,http://hackage.haskell.org/package/base-4.9.0.0/docs/Control-Exception-Base.html#v:bracket,它也在Scalaz中實現。 – 2016-09-29 09:01:07