【问题标题】:Throwing Exception in Foreach/Map Block在 Foreach/Map 块中抛出异常
【发布时间】:2015-05-14 12:37:51
【问题描述】:

我很好奇为什么会在下面的foreach 块中抛出异常。我希望没有值可以通过过滤器,因此永远不会到达 foreach 块。 map 也会发生同样的行为。

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

我希望异常不会被抛出,并且表现得更像下面的 println 永远不会执行。

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

也许这与如何处理异常有关?这是为什么呢?

【问题讨论】:

    标签: scala


    【解决方案1】:
    { throw new Exception }
    

    只是一个抛出异常的块——因此它的类型为Nothing。由于Nothing 是所有类型的子类型,它与Function[Int, T] 兼容,foreach 块的参数需要它。

    如果你事先创建函数,你可以更清楚地看到这一点:

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

    如果你想创建一个Function[Int, Nothing]你需要将参数添加到块中:

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

    【讨论】:

    • 换句话说,表达式throw new Exception 是函数foreach 的按值参数,因此在执行更大的表达式之前对其进行评估。 _ => throw new Exception 也首先被计算,但它计算为一个函数对象(当更大的表达式执行时,它永远不会被调用)。
    • @SteveWaldman 我认为这是一个更好的答案。 Lee 一目了然似乎指出了为什么会这样编译
    猜你喜欢
    • 1970-01-01
    • 2010-10-03
    • 1970-01-01
    • 2011-01-04
    • 2011-03-18
    • 1970-01-01
    • 2012-09-21
    相关资源
    最近更新 更多