匹配没有参数列表的案例类

时间:2013-11-19 22:43:22

标签: scala pattern-matching

我注意到关于没有任何参数列表的案例类(不是案例对象)的非常奇怪的行为。在尝试对它们进行模式匹配时,似乎完全忽略了超类型。我写了一个展示行为的小例子:

object TestMatch {
  trait CommonType
  case class A(val x:Int) extends CommonType
  case class B extends CommonType
  case object C extends CommonType

  def main(args: Array[String]): Unit = {
    printifmatched(A(1))
    printifmatched(B)
    printifmatched(C)
  }
  def printifmatched: PartialFunction[Any,Unit] = {
    case x: CommonType => println("This is a common type", x)
    case x => println("This is not a common type", x)
  }
}

该计划的输出如下:

(This is a common type,A(1))
(This is not a common type,B)
(This is a common type,C)

这是一个错误吗?任何人都可以解释为什么Scala会这样做吗?

2 个答案:

答案 0 :(得分:9)

这是因为B没有实例化B;它只是一个表示类型的对象:

scala> B
res0: B.type = B

B的对象也是特征CommonType的对象,但B的类型对象都不是。

添加括号实际上会实例化对象,因此它可以工作:

scala> B()
res1: B = B()

scala> printifmatched(B())
(This is a common type, B())

顺便说一下,不推荐使用括号来定义case类:

scala> case class B
<console>:1: warning: case classes without a parameter list have been deprecated;
use either case objects or case classes with `()' as parameter list.
       case class B
                   ^

它适用于case对象,因为对象不需要参数,因为它们不需要实例化。 C是对C类型(单例)实例的引用。

答案 1 :(得分:0)

关于 SLS 5.3.2案例类伴随对象(为案例类自动生成的内容)不是案例类的父类的子类型。 但是你用伴侣对象调用printifmatched

所以对于课堂来电:

printifmatched(new B)

或调用伴随对象的apply方法返回类实例什么是CommonType的子类:

printifmatched(B.apply())
//OR:
printifmatched(B())