通过 Scala 或 java 中的继承扩展一组命名值
Extending a set of named values via inheritance in scala or java
我知道有人问了很多关于枚举和特征的问题,但是我想从我必须讨论最优雅的方式的要求开始,我意识到枚举和特征都不可能完成这项工作。
首先考虑构成我的要求的这个简单示例
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
}
问题
如前所述,我意识到上面的两个例子都不符合要求。更多的是将它们从我记下的答案中排除。实际问题是,你将如何做到这一点?部分选项:
- 基于文件的配置
- 让开发人员在实现新功能时调整 Animal 的源代码。
- 还有什么?
谢谢!
The crucial part is that I want programmers to be able to check the list of allowed animals by typing in "Animal.".
您可以在不修改 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
问题出在 "somewhere visible from your code" 部分。它可以被导入,但是开发人员需要知道它存在才能导入它,这可能会破坏目的。它可以添加到现有位置,但为什么不首先将其添加到 Animal
?
一个简单的解决方案是为名称设置一个通用前缀:
trait Animal
case object AnimalDog extends Animal
case object AnimalCat extends Animal
然后自动完成将正常工作,只需键入 Animal
而无需 .
。
我知道有人问了很多关于枚举和特征的问题,但是我想从我必须讨论最优雅的方式的要求开始,我意识到枚举和特征都不可能完成这项工作。
首先考虑构成我的要求的这个简单示例
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
}
问题 如前所述,我意识到上面的两个例子都不符合要求。更多的是将它们从我记下的答案中排除。实际问题是,你将如何做到这一点?部分选项:
- 基于文件的配置
- 让开发人员在实现新功能时调整 Animal 的源代码。
- 还有什么?
谢谢!
The crucial part is that I want programmers to be able to check the list of allowed animals by typing in "Animal.".
您可以在不修改 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
问题出在 "somewhere visible from your code" 部分。它可以被导入,但是开发人员需要知道它存在才能导入它,这可能会破坏目的。它可以添加到现有位置,但为什么不首先将其添加到 Animal
?
一个简单的解决方案是为名称设置一个通用前缀:
trait Animal
case object AnimalDog extends Animal
case object AnimalCat extends Animal
然后自动完成将正常工作,只需键入 Animal
而无需 .
。