我有一个类和两个case子类:
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 = ???
但是,这会引起C1
和C2
签名中的weight
变量的问题,并要求我覆盖它。
我尝试并认为可行的一个解决方案是创建一个伴随对象:
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
但是我认为伴随对象不会被子类继承
- 我如何在不递归的情况下获得想要的结果?
- 更广泛地说,我如何赋予一个抽象类-- * 这个特定的字段在继承自我的子类中总是可用的,因此它应该是静态可用的,并且不会编译失败 *?
2条答案
按热度按时间68de4m5k1#
您应该将成员
weight: Int
添加到C
然后您可以匹配键入的模式
或构造函数模式
Why do we have a need for separate case identifiers in case of type only matching in scala?
通常,抽象成员是
def
s,在实现中被def
/val
/lazy val
(如果需要,为var
)覆盖。nr7wwzry2#
将
weight
添加到超类中是正确的方法,但是实际上必须在C1
中 * 定义 *weight
,这导致不需要开始模式匹配。