我正在一个项目中工作,我需要在其中标记收到的消息的类型。消息可以来自不同的来源,但所有这些来源都生成具有相同概念类型(因此,相同含义)但以不同方式编写的消息。
例如从 source1 我可以收到
来源1:
{
"message_type": "typeA",
"value": 3
...
}
或者
{
"message_type": "typeB",
"value": 3
...
}
但也从 source2 我可以收到
来源2:
{
"message_type": "A",
"value": 5
...
}
或者
{
"message_type": "B",
"value": 2
...
}
我想最大化代码重用,所以我尝试了这个解决方案。
我创建的第一个 Scala 文件是一个特征:
trait MessageType extends Enumeration {
val TYPE_A: Value
val TYPE_B: Value
}
然后我在两个目标文件中实现了它:
object Source1MessageType extends MessageType{
override val TYPE_A: Value("typeA")
override val TYPE_B: Value("typeB")
object Source2MessageType extends MessageType{
override val TYPE_A: Value("A")
override val TYPE_B: Value("B")
所以现在我想要的是在不知道源类型的情况下检查消息的类型,如下所示:
def foo(type: MessageType.Value) {
type match{
case MessageType.TYPE_A => ...do A action...
case MessageType.TYPE_B => ...do B action...
}
}
但是,如果我编写此代码,IDE (IntelliJ) 会以红色突出显示该参数,但不会提供有关错误的任何信息。似乎我只能使用 Source1MessageType 或 Source2MessageType 作为参数类型。
我认为错误是因为 Scala 没有将特征视为枚举,所以我无法访问枚举的值。
你有什么解决办法吗?
最佳答案
是的,您可以进行分层枚举。所以一般我会建议不要使用 Enumeration
.这是一篇关于为什么不好的文章
https://medium.com/@yuriigorbylov/scala-enumerations-hell-5bdba2c1216
最惯用的方法是利用这样的密封特性:
sealed trait MessageType{
def value:String
}
sealed trait MessageType1 extends MessageType
final case object TypeA extends MessageType1{
override def value:String = "typeA"
}
final case object TypeB extends MessageType1{
override def value:String = "typeB"
}
sealed trait MessageType2 extends MessageType
final case object A extends MessageType2{
override def value:String = "A"
}
final case object B extends MessageType2{
override def value:String = "B"
}
请注意,所有这些定义都需要在同一个文件中。现在这有效,因为
sealed
和 final
告诉编译器继承只能发生在这个文件中。这意味着给定一个
MessageType2
的实例编译器知道它只能是对象 A
或 B
它不能是其他任何东西(因为密封/最终)这为您提供了模式匹配等方面的详尽检查的枚举。
关于scala - 有没有办法在 Scala 中实现分层枚举?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54589703/