Scala - 模式匹配 MatchError

Posted

技术标签:

【中文标题】Scala - 模式匹配 MatchError【英文标题】:Scala - Pattern Matching MatchError 【发布时间】:2016-07-01 17:07:59 【问题描述】:

我正在玩模式匹配,但我很难理解这段代码有什么问题:

class Expr 
  case class Number(v : Int) extends Expr
  case class Sum(a : Expr, b : Expr) extends Expr

  def show(e: Expr): String = 
    e match 
      case Number(a) => a.toString() 
      case Sum(a, b) => "(" + show(a) + "+" + show(b) + ")"
    
  

  override def toString() = show(this)


class Number(v : Int) extends Expr 

class Sum(a : Expr, b : Expr) extends Expr 

object Number 
  def apply(v : Int) = new Number(v)

object Sum extends Expr 
  def apply(a : Expr, b : Expr) = new Sum(a, b)


object ExpressionProblem 
  def main(args: Array[String]) 
    val p =  Sum( Number(3),  Number(4))
    println( p )
  

当我尝试执行 println 时,它会抛出 MatchError。

Exception in thread "main" scala.MatchError: an instance of class week4.Expr$Sum
    at week4.Expr.show(ExpressionProblem.scala:8)
    at week4.Expr.toString(ExpressionProblem.scala:14)
    at java.lang.String.valueOf(String.java:2994)
    at java.io.PrintStream.println(PrintStream.java:821)
    at scala.Console$.println(Console.scala:148)
    at scala.Predef$.println(Predef.scala:315)
    at week4.ExpressionProblem$.main(ExpressionProblem.scala:31)
    at week4.ExpressionProblem.main(ExpressionProblem.scala)

【问题讨论】:

您正在发送Sum 类的实例,但试图匹配Sum 的实例case 类 【参考方案1】:

您正在发送Sum 类的实例,但试图匹配Sum 的实例case 类。删除类并使案例类对您的代码可见:

trait Expr   
  def show(e: Expr): String = e match 
    case Number(a) => a.toString() 
    case Sum(a, b) => "(" + show(a) + "+" + show(b) + ")"
  

  override def toString() = show(this)


case class Number(v : Int) extends Expr
case class Sum(a : Expr, b : Expr) extends Expr

object ExpressionNoProblem 
  def main(args: Array[String]) 
    val p = Sum(Number(3), Number(4))
    println(p)
  

【讨论】:

感谢您的解决方案。但我不明白这一点,你能解释一下有什么区别吗? 您定义了 Sum(和 Number)两次:一次作为内部案例类 Expr#Sum 另一次 - 作为常规类 Sum。您的匹配试图匹配 case class (Expr#Sum),但实际上您发送的是类实例 (Sum)。名称相似但类别完全不同 此外,常规类不能与unapply-style(提取器)case Sum(a,b) 进行模式匹配——它们只能作为类型匹配case s: Sum。见,docs.scala-lang.org/tutorials/tour/extractor-objects.html

以上是关于Scala - 模式匹配 MatchError的主要内容,如果未能解决你的问题,请参考以下文章

Scala 的位置:MatchError

线性回归 scala.MatchError:

scala.MatchError:某个时间点之后的所有请求都为空

scala.MatchError:运行sbt命令时为10

13scala模式匹配

Spark UserDefinedAggregateFunction:scala.MatchError 0.0(类 java.lang.Double)