2014-01-28 90 views
9

枚举值在匹配/大小写表达式中似乎失败。这是工作表中发生的情况。Scala枚举类型匹配失败/ case

object EnumType extends Enumeration { 
    type EnumType = Value 
    val a, b = Value 
    } 

    import EnumType._ 
    val x: EnumType = b    //> x : ... .EnumType.EnumType = b 

    x match { 
    case a => "a" 
    case b => "b" 
    }         //> res0: String = a 

    if (x == a) "a" else "b"   //> res1: String = b 

发生了什么事?谢谢。

+0

你应该得到一个警告,第二次'case'永远无法匹配,对不对? –

+0

.scala文件中的相同代码会生成警告,但不会出现在工作表中。 – RussAbbott

回答

16

像@凯文赖特和@李刚刚说的,ab作为变量模式,而不是EnumType值。

另一个选项来修复你的代码是摆明你引用从EnumType单值:

scala> x match { case EnumType.a => "a" case EnumType.b => "b" } 
res2: String = b 
+0

谢谢。这也适用。 – RussAbbott

1

a在您的case语句中是一个与任何匹配的未绑定变量。你需要明确检查值等于a

x match { 
    case v if v == a => "a" 
    case _ => "b" 
} 
+0

这与if-expression版本基本相同。 – RussAbbott

+0

看到其他两个答案,其实也解释了为什么会发生这种情况 –

8

abmatch块不如枚举值ab,模式匹配只会在第一场比赛x相同案件并将其绑定到一个新的价值a(第二种情况将被忽略)

为了避免这种情况,你有两个选择:

1)包装在反引号的值:)

x match { 
    case `a` => "a" 
    case `b` => "b" 
}  

2进行枚举值大写:

object EnumType extends Enumeration { 
    type EnumType = Value 
    val A, B = Value 
} 

import EnumType._ 
val x: EnumType = B 

x match { 
    case A => "a" 
    case B => "b" 
} 

鉴于这些值(所有意图的目的)常数,使用大写是比较常见的/惯用的解决方案。

请注意,只有首字母需要大写,而不是整个文字的名称。

+0

谢谢。我没有意识到案件陈述的大写或反义约定。 (PS。我检查了表示问题已被回答的复选标记,但是当我检查上面答案中的复选标记时,此答案变得没有选中。) – RussAbbott

+1

随时接受您最喜欢的任何岩石:)顺便说一句,您可以随时如果出现其他问题,请更改已接受的答案,您认为这更符合问题。 –

+0

我会尽量使它们成为大写,尊重命名约定,也不会被视为模式匹配中的值模式 –