如何让类型安全和编译器检查 Scala 中的枚举
How to have Type safe and compiler checked Enums in Scala
我在 SO 上看到了几个关于这个问题的问题,但仍然找不到很好的答案:
我想要一个 State Enum
,有 3 个状态:Good
、NotGood
和 Unknown
。
到目前为止,没什么大不了的。但由于状态来自外部 API(未记录,这就是 Unknown
状态的原因),它使用 snake case,所以我做了一个 findByName
转换:
object State extends Enumeration {
val Good = Value("good")
val NotGood = Value("not_good")
val Unknown = Value("unknown") // "unknown" ??
def findByName(name: String): State.Value = {
Try(State.withName(name)).getOrElse {
Logger.warn(s"Found unexpected result: $name")
Unknown
}
}
}
现在,有两个问题:
1st:我希望编译器警告我非穷尽匹配。这可以使用密封特征来实现,这引出了我的第二个问题
2nd:在 Unknown
的情况下,我想保存收到的值,但是 Enums
在定义时获取名称,而不是在构建时获取名称。但是如果我有一个密封的特征,就像this tutorial我怎么能定义这样的场景呢?
我得到了类似的东西:
sealed abstract class State(val name: String)
case object Good extends State("good")
case object NotGood extends State("not_good")
case object Unknown extends State("unknown")
不过,unknown
是硬编码的,我希望它是一个 argument/constructor 参数。
此外,我丢失了 findByname
属性...
While I prefer a solution using 'pure' Scala, would also like to see some solution with Shapeless or Cats
对于未知情况,您可以尝试使用 class:
case class Unknown(value: String) extends State("unknown")
...
def findByName (name: String) = name match {
case "good" -> Good
case "not_good" -> NotGood
case x -> Unknown(x)
}
我在 SO 上看到了几个关于这个问题的问题,但仍然找不到很好的答案:
我想要一个 State Enum
,有 3 个状态:Good
、NotGood
和 Unknown
。
到目前为止,没什么大不了的。但由于状态来自外部 API(未记录,这就是 Unknown
状态的原因),它使用 snake case,所以我做了一个 findByName
转换:
object State extends Enumeration {
val Good = Value("good")
val NotGood = Value("not_good")
val Unknown = Value("unknown") // "unknown" ??
def findByName(name: String): State.Value = {
Try(State.withName(name)).getOrElse {
Logger.warn(s"Found unexpected result: $name")
Unknown
}
}
}
现在,有两个问题:
1st:我希望编译器警告我非穷尽匹配。这可以使用密封特征来实现,这引出了我的第二个问题
2nd:在
Unknown
的情况下,我想保存收到的值,但是Enums
在定义时获取名称,而不是在构建时获取名称。但是如果我有一个密封的特征,就像this tutorial我怎么能定义这样的场景呢?
我得到了类似的东西:
sealed abstract class State(val name: String)
case object Good extends State("good")
case object NotGood extends State("not_good")
case object Unknown extends State("unknown")
不过,unknown
是硬编码的,我希望它是一个 argument/constructor 参数。
此外,我丢失了 findByname
属性...
While I prefer a solution using 'pure' Scala, would also like to see some solution with Shapeless or Cats
对于未知情况,您可以尝试使用 class:
case class Unknown(value: String) extends State("unknown")
...
def findByName (name: String) = name match {
case "good" -> Good
case "not_good" -> NotGood
case x -> Unknown(x)
}