如何从返回Int的scala中的递归函数抛出异常

时间:2015-05-10 22:45:00

标签: scala exception-handling

我最近开始学习scala并且作为赋值的一部分,我需要编写一个具有以下要求的函数:它必须是递归的,并且在空列表的情况下抛出异常。试过这段代码,但总是抛出异常。

def max(xs: List[Int]): Int =
  if (xs.isEmpty) {
    throw new NoSuchElementException("empty list")
  } else {
    if (xs.head > max(xs.tail)) xs.head else max(xs.tail)
  }
}

已编辑:抱歉有错误,当然需要使用new创建例外。但是,该函数始终失败并出现异常。 尝试过require(),但它返回一个Unit类型,因此编译器说它不能放在那里。 是否有一种简单的方法可以在scala中递归函数抛出异常而不解析为Try,Option和其他函数?

2 个答案:

答案 0 :(得分:5)

你正在尝试throw一堂课。在Scala中,就像在Java中一样,你只能抛出一个类的实例,而不是类本身。你必须使用NoSuchElementException的构造函数之一

throw new NoSuchElementException("Tried to find the maximum element of an empty list")

Scala还允许您通过提供OOTB Option类型来避免通过异常来传达故障。但如果你的作业要求你使用例外,那就这样吧。

答案 1 :(得分:3)

您的代码将始终抛出异常,因为递归将始终减少为空列表。我的假设是,如果列表为空,则不希望启动任何递归。在这种情况下,您可以定义一个内部函数来执行实际的递归。

def max(xs: List[Int]): Int = {

  if (xs.isEmpty) {
    throw new NoSuchElementException("empty list")
  }

  def iter(xs: List[Int], currMax: Int): Int = {

      if(xs.isEmpty) {
        currMax
      }
      else {
        iter(xs.tail, if(xs.head > currMax) xs.head else currMax)
      }
  }

  iter(xs.tail, xs.head)
} 

注意:以上只是一个尚未完成测试的快速,肮脏的示例。在风格上,这两个例子都可以像其他人所建议的那样使用模式匹配。