【发布时间】:2017-10-27 17:46:22
【问题描述】:
我有一个如下所示的 scala 类:
class Zoo {
val name: String
val location: String
val lion: Option[Object]
val tiger: Option[Object]
val bear: Option[Object]
}
使用 Zoo 的代码必须在运行时检查是否存在狮子、老虎和/或熊。我希望能够在编译时断言存在哪些动物。
目前我有以下内容:
class Zoo {
val name: String
val location: String
}
case class ZooWithBear(zoo: Zoo, bear: Bear)
case class ZooWithLion(zoo: Zoo, lion: Lion)
case class ZooWithTiger(zoo: Zoo, tiger: Tiger)
def foo(zooWithBear: ZooWithBear) : Int
当我想断言动物的组合必须存在时,这显然会失败——案例类别的数量会爆炸式增长。
我还可以使用 HasBear、HasLion 和 HasTiger 等特征。这在方法签名 (def foo(z: Zoo with HasLion)) 中效果很好,但是给定 Zoo 的实例具有一些未知的附加特征集,没有办法添加特征。 (通过某种zoo.withTiger(tiger): Self with HasTiger 类型的方法。)我必须了解动物园最初建造时的所有现有动物。
给定一个像 Zoo 这样具有公共属性的基类,我如何使用类型系统灵活地创建具有附加属性的 Zoo 实例,并在方法签名中断言传入的 Zoo 实例具有一组特定的附加属性?
【问题讨论】:
-
考虑这种关系。动物园有动物。 Zoo 是一个类,Animal 是一个类。关键字“with”应该告诉您存在链接关系,而不是涉及“is”关系。如果这有意义吗?因此,对于这个问题,适当的操作是布尔 hasAnimal(Animal animal) 等...然后您可以让 Animal 成为每个动物类的父类。
-
@ErickStone 我知道我在以违反 OO 原则的方式滥用类型系统,但我仍然想弄清楚它是否可能:-)。 hasAnimal(Animal animal) 听起来很合理,但它只在运行时有效。我希望能够在编译时做出断言。 (例如
def someMethod(zoo: Zoo with HasBear with HasTiger))