scala类出错:递归方法printExpr需要结果类型

scala类出错:递归方法printExpr需要结果类型,scala,Scala,我在网上遇到一个错误: case Sum(l, r) => printExpr(l); print("+"); printExpr(r) 错误是: 递归方法printExpr需要结果类型 这个代码看起来不错,我做错了什么 abstract class Expr { case class Num(n: Int) extends Expr case class Sum(l: Expr , r: Expr) extends Expr case class Prod(l: Expr

我在网上遇到一个错误:

case Sum(l, r) => printExpr(l); print("+"); printExpr(r)
错误是:

递归方法printExpr需要结果类型

这个代码看起来不错,我做错了什么

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中的每个方法都返回一些东西;“过程”只是返回type
Unit
的方法。这样做的语法是在方法的头之后省略
=
,但随后必须用大括号将方法体括起来(即使它是单个表达式,如
匹配
)。所以你可以做:

def printExpr(e: Expr) {
  e match {
    ...
  }
}

为了避免显式声明
Unit

printExpr(e:Expr)
一个返回类型,例如
String
Expr

printExpr(e : Expr): Expr
printExpr(e : Expr): String

Scala compile无法推断递归方法的类型,因此必须显式声明它:

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