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 代码中,match
是 String
。到目前为止,一切都很好。每个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枚举值的主要内容,如果未能解决你的问题,请参考以下文章