我知道很多关于枚举的问题和特征已经被问到,但是我想从我要讨论最优雅的方式开始,我意识到无论是枚举还是特质都不会起作用。
首先考虑形成我的要求的这个简单例子
trait Sound{
def makeSound(animal: Animal.value): String
}
关键部分是我希望程序员能够通过输入“Animal”来检查允许的动物列表。但是,列表应该能够通过新的实现进行扩展。由于这些原因,以下尝试失败。
特质实施
如果我将makeSound参数定义为Animal,这是可扩展的,但是使用该函数的程序员无法看到哪些动物可用。
trait Animal
case object Dog extends Animal
case object Cat extends Animal
枚举实施
这适用于要列出的可能值,但是如果我想扩展它,那么我需要创建一个新对象,使用新名称,这样就无法达到目的。
object Animal extends Enumeration {
type Animal = Value
val Dog, Cat = Value
}
问题 如上所述,我意识到上述两个例子都不符合要求。更多的是将它们从我记下来的答案中排除。实际的问题是,你会怎么做?一些选择:
谢谢!
答案 0 :(得分:3)
关键部分是我希望程序员能够通过输入“Animal”来检查允许的动物列表。
您可以在不使用implicits修改Animal
的情况下执行此操作:
trait Animal
object Animal
// somewhere visible from your code
implicit class CatAnimal(singleton: Animal.type) {
case object Cat extends Animal
}
// in your code
Animal.Cat // uses the implicit class
问题在于“代码可见的某个地方”部分。它可以导入,但是开发人员需要知道它存在才能导入它,这可能会破坏目的。它可以添加到现有的locaction中,但是为什么不首先将它添加到Animal
?
一个简单的解决方案是为名称添加一个公共前缀:
trait Animal
case object AnimalDog extends Animal
case object AnimalCat extends Animal
然后自动填充功能正常,只需在Animal
处输入.
即可。