Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala-匹配相关类型元组的模式_Scala_Pattern Matching_Tuples - Fatal编程技术网

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,完全失去了控制。