首页 > 解决方案 > 匹配有状态子类对象时,我可以避免在模式匹配中使用 asInstanceOf 吗?

问题描述

Var("x")当我对像or这样的表达式进行建模Number(7)并使用模式匹配编写一个 eval 函数时,我遇到了一个无法避免使用“asInstanceOf”方法的情况。

2 限制

sealed trait Expr
object Expr {
  def eval(e: Expr): Int = e match {
    case Number(n) => n
    case Var(_) => e.asInstanceOf[Var].getValue()
  }
}
case class Number(n: Int) extends Expr
case class Var(s: String) extends Expr {
  var value = 0
  def getValue(): Int = value
  def updateValue(x: Int): Unit = {
    this.value = x
  }
}
val x = Var("x")
x.updateValue(1)
Expr.eval(x) // 1

当我像这样定义第二种情况时:case Var(x) => Var(x).getValue(),我得到Expr.eval(x) // 0. 这是因为Var(x)在右侧会构造一个Var带有 value的新鲜事物0

我可以使用asInstanceOf,但在改进的意义上,我想知道是否有比 using 更清洁的解决方案asInstanceOf,我还没有找到。

标签: scalapattern-matchinginstanceof

解决方案


您可以使用@将变量绑定到模式。像这样使用它:

def eval(e: Expr): Int = e match {
    case Number(n) => n
    case v@Var(_) => v.getValue()
}

您还可以在模式匹配中检查变量的类型

def eval(e: Expr): Int = e match {
    case Number(n) => n
    case v: Var => v.getValue()
}

推荐阅读