2013-02-28 100 views
1

我的應用程序從文件讀取一些配置值。如果在這個過程中有任何錯誤,我想爲這些配置參數設置默認值。我做的是:Catch的返回值

val (param1, param2) = { 
    try{ 
    val props = new java.util.Properties 
    props.load(getClass.getResource("/myapp.properties").openStream) 
    (
     props.getProperty("param1", "default1"), 
     props.getProperty("param2", "default2") 
    ) 
    } 
    catch{ 
    case _ => ("default1", "default2") 
    } 
} 

我知道,如預期,如果有一個例外,我在catch塊正在做是行不通的。有沒有辦法解決它?我使用Scala的2.9

+1

爲什麼你認爲這不會按預期工作?你可能希望在捕捉什麼時候少一點混雜,但除此之外,它看起來可行,即使不是慣用的scala。 – Impredicative 2013-02-28 12:18:03

+0

@Impredicative:我已經嘗試將它改爲'case _ =>(「def1」,「def2」,「junk」),編譯器並沒有抱怨,我把它解釋爲一個表示結果可能被忽略的標誌。此外,大多數情況下,一個寫入返回「Unit」的東西(如打印錯誤消息等)。編譯器如何知道何時使用結果? – Eduardo 2013-02-28 12:19:49

+0

編譯器推斷返回類型。如果你返回不同的類型,它很可能會推斷「任何」。如有疑問,請明確指定返回類型:如果您錯誤地返回錯誤類型,將導致編譯錯誤。 – bluenote10 2013-02-28 12:26:57

回答

3

這是可行的,但它開闢了一個運行時錯誤的,因爲

val (a,b) = whatever 

的可能性,只要whateverTuple2 --in特別是超可稱爲,它可能是AnyRefAny,這實際上是try/catch返回值將被擴展到如果您有足夠不匹配的類型。您可以通過添加一個類型歸屬確保它是正確的類型:

val (a,b): (A, B) = whatever 

,然後,如果右手邊是不正確的類型,一路經過的try/catch類型檢查會抱怨。

例如:

val (a,b): (String, String) = try { 
    ("perch", if (scala.util.Random.nextBoolean) throw new Exception else "halibut") 
} catch { 
    case e: Exception => ("salmon", "herring") 
} 

如果你試圖"herring"後添加, "cod"你就會得到一個編譯時錯誤。如果重複輸入,這個任務會給你a = perch和b =比目魚一半的時間,a =鮭魚和b =鯡魚另一半。


附錄:在2.9(或以下,我想,雖然我還沒有檢查),你必須把類型歸屬的try/catch語句,像這樣:

val (a,b) = (try { 
    ("perch", if (scala.util.Random.nextBoolean) throw new Exception else "halibut") 
} catch { 
    case e: Exception => ("salmon", "herring") 
}): (String, String) 

到得到捕獲的類型檢查。

+0

你真的嘗試過嗎?我認爲你在'catch'中返回的內容會被忽略(例如,返回「Unit」比較常見) – Eduardo 2013-02-28 12:35:36

+0

Eduardo:不,它不是。我剛剛在Scala 2.10中進行了檢查。如果你使用:'val(param1,param2):Tuple2 [String,String] = ...'你將無法返回(「def1」,「def2」,「junk」)和(「def1」 42)。 – bluenote10 2013-02-28 12:37:38

+0

@ bluenote10:不幸的是我無法升級到2.10。這就是爲什麼我提到我在使用2。9 – Eduardo 2013-02-28 12:38:30