我有一个类和两个案例子类:
abstract class C
case class C1(left: C, right: C, weight: Int) extends C
case class C2(weight: Int) extends C
我想实现如下内容:
def weight(t: C): Int = {
t match {
case c1: C1 => l.weight
case c2: C2 => c2.left.weight + c1.right.weight //this line doesn't let the code compile
}
}
以上代码无法编译。说
left
和right
没有属性weight
。我看到这个是因为 C 没有为其定义权重。只有 c1
和 c2
可以。但是,我传递给 weight
函数的类实例将是 c1
或 c2
并且肯定会有权重。
它实际上是树上的递归权重求和,我可以通过以下方式实现:
def weight(t: C): Int = {
t match {
case c1: C1 => l.weight
case c2: C2 => weight(c2.left) + weight(c1.left)
}
}
但是,我不想递归,如果重量信息在我传入的实例中就可用,我认为我不必这样做。
这是我要解决的作业问题,类
C
、C1
和C2
的签名是神圣不可侵犯的。我试过修改
abstract class C
到
abstract class C:
val weight: Int = ???
但是,这随后开始引发
weight
和 C1
签名中的 C2
变量的问题,并要求我覆盖它。
我尝试并认为可行的一个解决方案是创建一个伴生对象:
abstract class CodeTree
object CodeTree:
val weight: Int = ???
case class Fork(left: CodeTree, right: CodeTree, chars: List[Char], weight: Int) extends CodeTree
case class Leaf(char: Char, weight: Int) extends CodeTree
但是我觉得伴生对象不会被子类继承
你应该添加成员
weight: Int
到C
abstract class C:
def weight: Int
case class C1(left: C, right: C, weight: Int) extends C
case class C2(weight: Int) extends C
然后你可以匹配输入的模式
def weight(t: C): Int =
t match
case c1: C1 => c1.left.weight + c1.right.weight
case c2: C2 => c2.weight
或构造函数模式
def weight(t: C): Int =
t match
case C1(l, r, _) => l.weight + r.weight
case C2(w) => w
如果类型仅在 Scala 中匹配,为什么我们需要单独的案例标识符?
通常抽象成员是
def
,并在实现中用def
/val
/lazy val
(var
如果需要)覆盖。