Scala-匹配相关类型元组的模式
我有以下类层次结构:Scala-匹配相关类型元组的模式,scala,pattern-matching,tuples,Scala,Pattern Matching,Tuples,我有以下类层次结构: class A class B extends A class C extends A 然后,还有另一个类,它获取这些类的实例,还有一个方法,其中有两种模式匹配的情况,如下所示: class D (one: A, two: A) { def work { (one, two) match { case (o, t): (B, B) => ... blablabla case (o, t): (B, C) => ... bl
class A
class B extends A
class C extends A
然后,还有另一个类,它获取这些类的实例,还有一个方法,其中有两种模式匹配的情况,如下所示:
class D (one: A, two: A) {
def work {
(one, two) match {
case (o, t): (B, B) => ... blablabla
case (o, t): (B, C) => ... blablabla
case _ =>
}
}
}
但是,当它应该解决有利于第二种情况的匹配时,(B,C)
,它尝试将其解析为(B,B)
,并产生类强制转换异常,C不能强制转换为B
。为什么?怎么办?我怎样才能克服这个问题 我让这段代码起作用了。
首先,我在类定义中添加了一个案例
case class A
case class B extends A
case class C extends A
其次,我更改了工作
class D(one: A, two: A) {
def work {
(one, two) match {
case (o: B, t: B) => println("BB")
case (o: B, t: C) => println("BC")
case (o: C, t: C) => println("CC")
case _ => println("AA")
}
}
}
现在我得到的是:
new D(B(),B()).work => BB
new D(B(),C()).work => BC
new D(C(),C()).work => CC
new D(A(),B()).work => AA
案例添加了apply和unapply方法。您的语法不太正确(无法编译)
不过,这是可行的:
object Matcher extends App {
class A
class B extends A
class C extends A
class D(one: A, two: A) {
def work {
(one, two) match {
case (o: B, t: B) => println("B")
case (o: B, t: C) => println("C")
case _ =>
}
}
}
val d1 = new D(new B, new B)
val d2 = new D(new B, new C)
d1.work
//B
d2.work
//C
}
和往常一样,问题在于删除了类型(B,C)
是Tuple2[B,C]
的语法糖,它在运行时被擦除为Tuple2
。case语句验证(B,C)
是否匹配Tuple2
,但随后无法强制转换它
在您的情况下,最简单的解决方案是分别匹配“1”和“2”,而不是将它们包装在元组中:
one match {
case o : B => two match {
case p : C => ...
case p : B => ...
}
...
}
它不太漂亮,但不会有同样的问题
编辑:事实上,我会使用Brian Smith的解决方案——在元组内部匹配,而不是外部匹配。它以类似的方式避免了问题,但看起来更好。是的,案例类。。。但是他们在继承方面有缺陷。。如果他们能在某个时候解决这个问题,我会非常高兴的……这段代码不会在现代Scala中编译,因为我认为从2.9开始,case继承就被禁止了@这不是一个bug,这是由design@NikitaVolkov我从REPL(Scala 2.9.1)复制了这段代码。它确实编译了。@T.Grottker,我肯定不是没有警告的。在Scala 2.10中,它没有compile@NikitaVolkov不,事实上我很清楚地记得他们告诉我,由于编译器和JVM或类似的技术问题,实现正确的继承非常困难,而同时的实现包含bug,即“使用时有您自己的风险-它可能会工作,也可能会坏”。Idk下一步该怎么办,也许他们已经明确禁止这种继承。。因为几年前我放弃了Scala,完全失去了控制。