Scala Case类匹配编译错误和别名内部类型?
如何使用与别名类型匹配的案例类?当我从容器中取出CB等时,这就有效.
class DoStuff[TKey]( val c : Container[TKey]#CB ) { type CB = Container[TKey]#CB type C1 = Container[TKey]#C1 type C2 = Container[TKey]#C2 c match { case C1(e1) => e1 // - not found: value e1 - not found: value C1 case C2(e2) => e2 // - not found: value e2 - not found: value C2 } } trait Container[TKey] { abstract trait CB case class C1(val e : AnyRef) extends CB case class C2(val e : AnyRef) extends CB } 谢谢! 解决方法
对…… Scala中的内部类有点繁琐.在我向您展示您提供的代码的重写版本之前,让我们尝试一个简单的示例.
case class Foo(x: Int) { case class Bar(y: String) } 现在,请考虑以下代码段: val x = new Foo(1) val y = new Foo(2) val a = new x.Bar("one") val b = new y.Bar("two") 最通用的a和b类型是Foo#Bar,这意味着内部类Bar具有任何类型为Foo的外部对象.但是我们可以更具体地说a的类型是x.Bar而b的类型是y.Bar – 这意味着a是内部类Bar的实例,外部对象x,类似于b. 实际上,您可以通过调用typeOf(a)和typeOf(b)来查看类型是不同的,其中typeOf是一个定义为此类的实用程序方法. (它只是通过非常好的类型推断和一些Manifest的使用来给出它的参数类型) def typeOf[T](x: T)(implicit m: scala.reflect.Manifest[T]) = m.toString 当内部对象保存对其封闭对象的引用时,如果不以某种方式指定其外部对象,则无法实例化内部对象.因此,您可以调用新的x.Bar(“one”),但不能调用新的Foo #Bar(“?”) – 在第二种情况下,您没有指定您尝试的新对象的内部对象是什么构造. 那么,让我们回到你的代码片段.当你进行模式匹配时,你实际上是在调用一个构造函数 – 当调用C1(e1)时.由于C1是Container [TKey]#C1的别名 trait Container[TKey] { abstract trait CB case class C1(val e : AnyRef) extends CB case class C2(val e : AnyRef) extends CB } class DoStuff[TKey] (val c: Container[TKey],val element: Container[TKey]#CB) { element match { case c.C1(e1) => Some(e1) case c.C2(e2) => Some(e2) case _ => None } } 现在这个编译,并希望它做你想要的.但要小心谨慎!由于类型擦除,Scala不能保证该元素实际上是c.CB类型或d.CB类型,其中c和d的情况下的CB恰好相同. 考虑这个例子: def matcher(arg: Foo#Bar) = { arg match { case x.Bar(n) => println("x"); case y.Bar(n) => println("y"); } } 其中x和y和以前一样.尝试运行以下内容: matcher(a) matcher(b) 他们都打印x! 因此,我会重写代码以在容器中显式地拥有一个元素: trait Container[TKey] { abstract trait CB case class C1(val e : AnyRef) extends CB case class C2(val e : AnyRef) extends CB val element: CB } class DoStuff[TKey](val c: Container[TKey]) { c.element match { case c.C1(e1) => Some(e1) case c.C2(e2) => Some(e2) case _ => None } } 希望能帮助到你 :) – Flaviu Cipcigan (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |