scala - Scala 类 : recursive method printExpr needs result type 上的错误

标签 scala

我在网上收到一个错误:

case Sum(l, r) => printExpr(l); print("+"); printExpr(r)

错误是:

recursive method printExpr needs result type



这段代码对我来说没问题,我做错了什么?
abstract class Expr {

  case class Num(n: Int) extends Expr
  case class Sum(l: Expr , r: Expr) extends Expr
  case class Prod(l: Expr, r: Expr) extends Expr

  def evalExpr(e: Expr): Int = e match {
    case Num(n) => n
    case Sum(l, r) => evalExpr(l) + evalExpr(r)
    case Prod(l, r) => evalExpr(l) * evalExpr(r)
  }

  def printExpr(e: Expr) = e match {
    case Num(n) => print(" " + n + " ")
    case Sum(l, r) => printExpr(l); print("+"); printExpr(r)
    case Prod(l, r) => printExpr(l); print("x"); printExpr(r)
  }
}

最佳答案

Scala 中的递归方法需要明确声明的返回类型,如错误消息所述。

原因是 Scala 从方法主体中使用的类型推断方法的返回类型。当方法的返回类型影响方法体中使用的类型时(因为它递归地调用自己),Scala 无法确定它应该分配给方法的类型,因此它要求您在源代码中这样做(正如您对 evalExpr 所做的那样,您明确表示它返回 Int )。

在这种情况下,您需要 printExpr有返回类型 Unit ,这是没有信息的无趣值的类型。通常调用返回类型为 Unit 的方法只是为了它的副作用(例如 print )。

所以你可以改变 printExpr 的标题行到:

def printExpr(e: Expr) : Unit = e match {

或者,Scala 有一些语法糖来声明“过程”。您可以将“过程”视为不返回任何内容,而只是执行一些代码,但实际上 Scala 中的每个方法都会返回一些内容; “过程”只是返回类型 Unit 的方法.这样做的语法是省略 =在方法的头之后,但是你必须用大括号将方法体括起来(即使它是一个单一的表达式,比如你的 match )。所以你可以这样做:
def printExpr(e: Expr) {
  e match {
    ...
  }
}

避免明确声明 Unit .

关于scala - Scala 类 : recursive method printExpr needs result type 上的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13260275/

相关文章:

java - Scala 有什么好处?

java - org.json.XML 转换 json 到 xml 到 json 失败

scala - Scala 中具有默认值的通用类型解析

Scala:k 折交叉验证

scala - 在 Scala 中创建一个懒惰的 var

scala - 特征之间的差异?

scala - 使用整数将相同的行添加到 Spark Dataframe

scala - 如何使用 spark 流读取 .csv 文件并使用 Scala 写入 parquet 文件?

scala - Future 和 future 和有什么不一样?

scala - 折叠操作中@unchecked 的正确语法是什么