【问题标题】:How to throw an exception from a recursive function in scala that returns Int如何从返回Int的scala中的递归函数抛出异常
【发布时间】:2015-05-10 22:45:00
【问题描述】:

我最近开始学习 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 和其他?

【问题讨论】:

  • 你必须创建一个新的异常来抛出:throw new NoSuchElementException。该问题与递归或Int无关。
  • Psst,你的递归总是以空的情况结束。可能想对此做点什么,因为大概你不总是想抛出异常。
  • 或者你可以看看scala.util.Try
  • 您可以插入 require(xs.length > 0, "empty list) 作为函数定义的第一行。这将引发 java.lang.IllegalArgumentException 并显示消息“requirement failed: empty array” .
  • 尝试对列表元素的各种排列使用模式匹配,它应该使您的基本情况更清晰。要构建递归列表操作,请从可能的最小输入开始,并在添加元素时考虑它的行为。

标签: scala exception-handling


【解决方案1】:

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

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)
} 

注意:以上只是一个快速、肮脏的示例,尚未完成测试。在风格上,这两个示例都将受益于其他人建议的模式匹配的使用。

【讨论】:

    【解决方案2】:

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

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

    Scala 还允许您通过提供 OOTB Option 类型来避免通信失败。但是,如果您的作业要求您使用例外,那就这样吧。

    【讨论】:

    • 你觉得IllegalArgumentExceptionNoSuchElementException更有意义吗?参数不合法的原因是因为里面没有元素!
    • @RexKerr 按照我理解文档的方式,NoSuchElementException 应该在非常具体的上下文中使用。表示您在获取下一个元素之前未能检查 Enumeration 中是否存在元素。 IllegalArgumentException 更通用,与NoSuchElementException 相比,它在此上下文中的使用与其文档更一致。
    • 是的,Scala 标准库在很多不涉及Enumeration 的地方使用NoSuchElementException
    • @SethTisue,@mucaho,很公平。删除了关于IllegalArgumentException
    猜你喜欢
    • 2020-03-18
    • 1970-01-01
    • 2012-09-21
    • 2018-01-13
    • 1970-01-01
    • 2017-08-13
    • 1970-01-01
    • 1970-01-01
    • 2022-08-03
    相关资源
    最近更新 更多