Scala模式匹配Java枚举值

Posted

技术标签:

【中文标题】Scala模式匹配Java枚举值【英文标题】:Scala pattern matching Java enum value 【发布时间】: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 => 【参考方案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

【讨论】:

以上是关于Scala模式匹配Java枚举值的主要内容,如果未能解决你的问题,请参考以下文章

小记--------scala-模式匹配

12.scala的模式匹配

scala 模式匹配 对值变量类型,Array,list中元素匹配

必会Scala之模式匹配和样例类

scala

Scala 匹配模式