2015-05-14 26 views
9

我很好奇爲什麼在下面的foreach塊中拋出異常。我希望沒有值使它通過過濾器,因此永遠不會到達該塊。與map發生相同的行爲。在Foreach/Map Block中拋出異常

scala> (1 to 10) filter { _ > 12 } foreach { throw new Exception } 
java.lang.Exception 
    ... 33 elided 

我期望的異常沒有拋出,並表現得更像下面這樣永遠不會執行println哪裏。

scala> (1 to 10) filter { _ > 12 } foreach { println _ } 

也許這與如何處理異常有關?爲什麼是這樣?

回答

7
{ throw new Exception } 

只是其拋出異常的塊 - 結果它具有類型Nothing。由於Nothing是所有類型的子類型,因此它與作爲foreach塊參數所需的Function[Int, T]兼容。

你可以看到這個更清楚,如果你創建預先的功能:如果你想創建你所需要的參數添加到塊Function[Int, Nothing]

//throws exception 
val f: Function[Int, Unit] = { throw new Exception } 

(1 to 10) filter { _ > 12 } foreach { _ => throw new Exception } 
+5

換句話說,表達式'throw new Exception'是函數foreach的一個值類型的參數,所以它在執行較大的表達式之前被評估。 '_ => throw new Exception'也會首先被評估,但它的計算結果是一個函數對象(當執行較大的表達式時,它永遠不會被調用)。 –

+1

@SteveWaldman我認爲這是一個更好的答案。李的一目瞭然似乎指出爲什麼這編譯 –