【问题标题】:Multiple Values for one enum一个枚举的多个值
【发布时间】:2014-09-21 01:04:16
【问题描述】:

所以我正在创建一个解析器来解析我们的客户工程师制作的一些配置文件。我并不特别信任我们的客户工程师。他们通常可以正确拼写,但他们永远不记得要大写什么。这使得Enum 类有点讨厌,因为它们会破坏程序导致Enum 失败,如果他们没有输入正确的字符串。

这是我的枚举类:

object EnumLayoutAlignment extends Enumeration
{
     type Alignment = Value
     val Vertical = Value("Vertical")
     val Horizontal = Value("Horizontal")
}

有没有办法让“垂直”、“垂直”和“垂直”都映射到同一个枚举值?

编辑:@Radai 在输入中提出了一个很好的观点,即 .upper() 但我也想包括“vert”和其他类似的输入

我以this为例

【问题讨论】:

  • 为什么不把所有东西都大写?
  • 问题是我们的客户工程师仍然不会记得...恕我直言,我希望这是用户证明
  • 我的意思是接受他们的输入(==您的代码从 conf 文件中读取的任何值),并将其大写。还是您的意思是他们将直接使用代码而不是您控制的某个界面?
  • @radai 不错,但我还想添加一些其他可能的映射
  • 为什么在函数式语言中使用 Enum 而不是抽象数据类型?

标签: scala enums enumeration


【解决方案1】:

解决这个问题的一种方法是提供一种反序列化方法:

def fromString(s: String) = s.upper() match {
  case "VERTICAL" | "VERT" | "V" => Some(Vertical)
  case "HORIZONTAL" | "HORIZ" | "H" => Some(Horizontal)
  case => None
}

那么使用就这么简单:

EnumLayoutAlignment.fromString(someInput).map(doThingWithValidEnum)

【讨论】:

    【解决方案2】:

    您可以将这样的方法添加到您的Enumeration

    def tryAsHardAsPossibleToFindMatch(s: String) = {
      val ls = s.toLowerCase
      val fv = values.filter(_.toString.toLowerCase.startsWith(ls))
      fv.size match {
        case 1 => fv.head
        case 0 => sys.error("No matching value for " + s)
        case _ => sys.error("Ambiguous values for " + s)
      }
    }
    

    这将允许您使用任何字符串,无论大小写如何,它是Value 开头的一部分。所以Vertical可以用“VERT”、“vErTi”、“vERTICAL”、“VerticaL”等来获得。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-26
      • 1970-01-01
      • 2018-11-05
      • 2019-01-29
      相关资源
      最近更新 更多