我有以下代码:
sealed trait A
case class B[T](v: T) extends A
case class C[T](v: T) extends A
object Test {
def swap(a: A): A = a match {
case a: B[t] => C[t](a.v) // works!
case C[t](v) => B[t](v) // error: C[t] does not take parameters
}
}
我希望这两种情况都失败,或者两种情况都能奏效。第二种情况的错误含义是什么?是否有语法解构参数化案例类?
注意:这里,' t'小写是必不可少的。如果它是' T',检查员将在方法的类型参数中查找它。
答案 0 :(得分:6)
执行a match { case C(v) => ??? }
时,您实际上会调用unapply
随播广告对象的C
方法,如下所示:C.unapply(a) match {Some(v) => ???}
只有一个C
个对象,而不是C[t]
的整个系列。没有任何对象可以称为C[Int]
,因此case C[t](v) =>
没有意义。
在您的示例中,您使用B[t]
作为类型,而不是模式,以及它的工作原理。请注意,虽然匹配可能会成功,但由于类型擦除,您无法在t
中获得任何内容。
当你调用C[t](a.v)
时,首先,编译器会删除类型t
,其次,这会被重写为对伴随对象的apply
方法的调用:{{ 1}}。请注意,type参数位于方法调用上,而不是在对象上。
答案 1 :(得分:1)
简单地说,它不是语言的一部分。
在此位置使用时,编译器正在查找环境中的类型,就好像它是通常的大写类型一样。您尝试执行的类型捕获似乎仅适用于案例陈述的case x:Y[z] => ...
形式。
以这种方式进行类型捕获并不是该语言的一个众所周知的部分,并让我运行到Scala reference document以获取详细信息(第8.3节)。我个人觉得这里大小写的区别不是我喜欢的。
在您的示例中,t
采用Any
类型,因为A
无法提供参数的类型信息。