【问题标题】:Scala pattern matching Java enum valueScala模式匹配Java枚举值
【发布时间】:2014-04-10 11:30:27
【问题描述】:

我有我的 java 枚举,例如:FOO("foo")BAR("bar") ... 我有一个getValue() 方法来返回枚举的值"foo""bar",这必须在Java 中。

另一方面,我必须在 Scala 中匹配这个:

result match {
  case "foo" =>

我正在努力:

result match {
  case Enum.FOO.getValue() => 

我得到这个错误:

method getValue is not a case class constructor, nor does it have an
unapply/unapplySeq method

我不太确定这里发生了什么,因为我的 getValue() 方法返回一个 String 那么为什么我不能将它用于模式匹配?谢谢

【问题讨论】:

  • 如果这是一个枚举,为什么不在枚举值本身而不是它们的“字符串表示”上做这种情况呢?否则,您总是可以创建一个“反向查找”方法,该方法将从其字符串表示中返回枚举值
  • 结果来自 DB,它是 String 类型并且匹配枚举的字符串 rep。我试图在这里匹配字符串值,所以我认为反向查找不会起作用,不是吗?你能给我看一些例子吗?干杯
  • 等一下。在您的 Scala 代码中,matchString。到目前为止,一切都很好。每个case需要什么处理?不能是枚举本身的方法实现吗?
  • @Duc:尝试删除括号:case Enum.FOO.getValue =>

标签: java regex scala enums pattern-matching


【解决方案1】:

JMPL 是一个简单的 java 库,它可以模拟一些特征模式匹配,使用 Java 8 特性。这个库可以很好地使用枚举。

   matches(myEnum).as(
      MyEnum.FOO,  () ->  System.out.println("FOO value");
      MyEnum.BAR,  () ->  System.out.println("BAR VALUE");
      Else.class,  () ->  System.out.println("Default value: " + data)
   );  

【讨论】:

    【解决方案2】:

    您可以对 Java 枚举进行模式匹配,但您不能在匹配的解构部分调用方法。所以这行得通:

    j match { case Jenum.FOO => "yay"; case _ => "boo" }
    

    如果 j 是您的 Java 枚举的一个实例(巧妙地标记为 Jenum)。

    但是你可以这样做:

    "foo" match {
      case s if s == Jenum.FOO.getValue => "yay"
      case _                            => "boo"
    }
    

    或者您可以先将字符串转换为枚举:

    Jenum.values.find(_.getValue == "foo") match {
      case Some(Jenum.FOO) => "yay"
      case _               => "boo"
    }
    

    (您可能还想先解开选项以避免重复Some(...) 这么多次)。

    作为参考,这是我使用的测试枚举(Jenum.java):

    public enum Jenum {
      FOO("foo"), BAR("bar");
    
      private final String value;
      Jenum(String value) { this.value = value; }
    
      public String getValue() { return value; }
    }
    

    【讨论】:

    • 我一直使用静态方法在枚举中搜索值,谢谢你的find建议:)
    • 感谢您的查找提示,这就是我一直在寻找的内容
    【解决方案3】:

    您收到评论“方法”。所以 scala 不会评估你的函数。它试图调用 unapply on 方法。

    您可以实现类似(在 MyEnum 类中):

     public static MyEnum fromText(String text) {
            for (MyEnum el : values()) {
                if (el.getValue().equals(text)) {
                    return el;
                }
            }
            return null;
        }
    

    然后

    MyEnum.fromText("foo") match{
     case FOO => ..
    }
    

    【讨论】:

      【解决方案4】:

      您不能将方法调用结果用作模式。相反,只需写

      if (result == YourEnum.FOO.getValue()) { 
        ... 
      } else if {
        ...
      }
      

      try {
        val resultAsEnum = YourEnum.valueOf(result)
      
        resultAsEnum match {
          case YourEnum.FOO => ...
          ...
        }
      } catch {
        case e: IllegalArgumentException => // didn't correspond to any value of YourEnum
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-05
        • 1970-01-01
        • 2014-02-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多