【问题标题】:Scala diamond prob, find class name from instance of class DScala diamond prob,从 D 类的实例中查找类名
【发布时间】:2016-01-31 14:30:23
【问题描述】:

在典型的菱形问题层次结构中,我有四个特征 A、B、C 和 D。 我在 trait A 中实现了一个方法 calculate,它检查 callerObject 的实例,执行一些计算并返回 trait A 类型的对象。当 callerObject 属于特征 B 或 C 但不适用于特征 D 的对象时,calculate 方法能够成功检查 callerObject 的 instanceType,并且我得到以下类转换异常:

java.lang.ClassCastException: packageName.B$$anon$1 cannot be cast to packageName.D

您能否建议前进的方向,如何在特征 A 的方法中从特征 D 中检查对象的类型。

PS:我是 Scala 新手。

【问题讨论】:

  • def calculate(other: A) : A = { this match { case _: B => //Some Function call and return B type obj case _: C => //Some Function call and return C type obj case _: D => //某个函数调用并返回D type obj } }
  • 不,我看不懂这个。将其添加到您的原始问题中,正确格式化,并显示您得到错误的位置。也添加类定义。在这里查看指导:stackoverflow.com/help/mcve
  • 我很快就会发布干净的代码。

标签: scala diamond-problem


【解决方案1】:

模式匹配case 语句的顺序很重要。确保最具体的类总是在顶部匹配。例如如果B extends AC extends B,这意味着C 的对象将始终匹配任何寻找B 或A 等的对象。

这是一个可以更好地解释解决方案的玩具示例:

sealed trait A {
   def calculate(i: A) = i match {
      case _:D => "d" // Make sure the D is checked first!
      case _:B => "b"
      case _:C => "c"
      // If you want to match for A make sure it is added last
   }
}
trait B extends A
trait C extends A
trait D extends B with C

这是 REPL 中的一个示例:

val b = new B{}
val c = new C{}
val d = new D{}

b.calculate(b)
res> "b"
b.calculate(c)
res> "c"
b.calculate(d)
res> "d"

【讨论】:

  • 完全按照上面的建议更改顺序对我有用,非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-30
  • 2014-05-31
  • 1970-01-01
  • 1970-01-01
  • 2017-03-21
  • 2022-01-27
  • 1970-01-01
相关资源
最近更新 更多