2015-05-14 126 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我认为这是一个更好的答案。李的一目了然似乎指出为什么这编译 –