案例类匹配类型

时间:2016-06-04 16:16:14

标签: scala algebraic-data-types

如果我尝试匹配其类型的变量,例如下面的代码:

object CaseClassesApp extends App {

  sealed trait A{}
  final case class B() extends A{} 
  final case class C() extends A{}

  def tryMatch(x: Any): String = x match {
    case B => "It's a B!"
    case C => "It's a C!"
    case _ => "nope"
  }

  var testB = new B()
  print(tryMatch(testB))
}

它不应该给我“这是一个B!”?为什么我会收到“nope”?

3 个答案:

答案 0 :(得分:3)

如果要键入匹配,可以通过稍微修改代码来实现它。

def tryMatch(x: Any): String = x match {
  case b:B => "It's a B!"
  case c:C => "It's a C!"
  case _ => "nope"
}

答案 1 :(得分:1)

模式匹配应为:

  def tryMatch(x: Any): String = x match {
    case B() => "It's a B!"
    case C() => "It's a C!"
    case _ => "nope"
  }

因为你想匹配对象而不是类型

如果您想匹配类型,可以使用TypeTag,例如:

  import scala.reflect.runtime.universe._
  def tryMatch[T](x: T)(implicit t: TypeTag[T]): String = x match {
    case _ if t.tpe =:= typeOf[B] => "It's a B!"
    case _ if t.tpe =:= typeOf[C] => "It's a C!"
    case _ => "nope"
  }

答案 2 :(得分:0)

其他答案解释了如何修复它,但不解释实际上是什么问题。每个case class会自动拥有一个同名的objectcase B,因此case None在匹配Option时就像x一样:在{{1}时匹配x: Any等于这个对象!如果用x: A替换B,编译器会告诉您匹配不可行,因为对象A不是preg_replace的实例。