Scala将String转换为Enumeration值的安全方式

Nya*_*vro 25 scala

假设我有枚举:

object WeekDay extends Enumeration {
  type WeekDay = Value
  val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value
}
Run Code Online (Sandbox Code Playgroud)

我希望能够将String转换为WeekDay值,这很好用:

scala> WeekDay.withName("Tue")
res10: WeekDay.Value = Tue
Run Code Online (Sandbox Code Playgroud)

但是,如果我传递一些'未知'值,我会得到例外:

scala> WeekDay.withName("Ou")
java.util.NoSuchElementException: None.get
  at scala.None$.get(Option.scala:322)
  at scala.None$.get(Option.scala:320)
  at scala.Enumeration.withName(Enumeration.scala:124)
  ... 32 elided
Run Code Online (Sandbox Code Playgroud)

是否有一些优雅的方法可以安全地将String转换为枚举值?

Sha*_*nds 41

您可以向枚举添加方法以返回Option[Value]:

def withNameOpt(s: String): Option[Value] = values.find(_.toString == s)
Run Code Online (Sandbox Code Playgroud)

注意:现有withName方法实际上就是这样,然后调用getOrElse在"else"情况下抛出异常.

  • 希望这是标准库的一部分,毕竟它是惯用的Scala,有一种安全的做事方式. (5认同)

Jav*_*deh 7

在@Shadowlands的答案的基础上,我将此方法添加到枚举中以具有默认unknwon值,而无需处理选项:

def withNameWithDefault(name: String): Value =
  values.find(_.toString.toLowerCase == name.toLowerCase()).getOrElse(Unknown)
Run Code Online (Sandbox Code Playgroud)

所以枚举看起来像这样:

object WeekDay extends Enumeration {
  type WeekDay = Value
  val Mon, Tue, Wed, Thu, Fri, Sat, Sun, Unknown = Value

  def withNameWithDefault(name: String): Value = 
    values.find(_.toString.toLowerCase == name.toLowerCase()).getOrElse(Unknown)
}
Run Code Online (Sandbox Code Playgroud)