如何在Scala中使用Type safe和编译器检查Enums

时间:2016-03-13 20:23:41

标签: scala enums shapeless scala-cats

我在这个问题上看到了几个关于SO的问题,但仍然找不到一个非常好的答案:

我希望有一个State Enum,其中包含3个州:GoodNotGoodUnknown

到现在为止,没什么大不了的。但由于状态来自外部API(没有记录,这就是Unknown状态的原因),它使用了蛇案例,因此我进行了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
    }
  }
}

现在,有两个问题:

  • 第一:我希望编译器警告我非详尽的匹配。这可以通过使用密封特性来实现,这导致了我的第二个问题

  • 第二:在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是硬编码的,我希望它是参数/构造函数参数。

另外,我丢失了findByname属性......

  

虽然我更喜欢使用'纯'Scala的解决方案,但也希望看到一些使用Shapeless或Cats的解决方案

1 个答案:

答案 0 :(得分:2)

您可以尝试使用类来表示未知案例:

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) 
}
相关问题