与多个匹配匹配的模式
请考虑以下Scala代码。与多个匹配匹配的模式
val a = "both"
a match {
case "both" | "foo" => println ("foo") // case 1
case "both" | "bar" => println ("bar") // case 2
}
我想match
工作,所以,如果a == "both"
,斯卡拉将执行两种情况。这是可能的还是有其他方法可以实现我想要的?
标准模式匹配将始终仅在一个案例中匹配。您可以通过使用的事实,图案可作为部分功能被视为亲近你想要什么(见Language Specification,第8.5节,模式匹配匿名函数),并定义自己的匹配运算,虽然:
class MatchAll[S](scrutinee : =>S) {
def matchAll[R](patterns : PartialFunction[S,R]*) : Seq[R] = {
val evald : S = scrutinee
patterns.flatMap(_.lift(evald))
}
}
implicit def anyToMatchAll[S](scrut : =>S) : MatchAll[S] = new MatchAll[S](scrut)
def testAll(x : Int) : Seq[String] = x matchAll (
{ case 2 => "two" },
{ case x if x % 2 == 0 => "even" },
{ case x if x % 2 == 1 => "neither" }
)
println(testAll(42).mkString(",")) // prints 'even'
println(testAll(2).mkString(",")) // prints 'two,even'
println(testAll(1).mkString(",")) // prints 'neither'
语法稍微偏离平常,但对我来说,这样的构造仍然是Scala强大的见证。
你的例子是现在写为:
// prints both 'foo' and 'bar'
"both" matchAll (
{ case "both" | "foo" => println("foo") },
{ case "both" | "bar" => println("bar") }
)
(编辑huynhjl指出,他给了一个令人震惊的相似答案this question)
这是一个非常干净的解决方案。做得好! –
+1“scrutinee” –
这让我想起http://*.com/questions/6720205/idiomatic-way-to-convert-a-seqb/6720659#6720659。名字'=> S'有什么好处? – huynhjl
一种可能的方式可以是:
val a = "both"
a match {
case "foo" => println ("foo") // Case 1
case "bar" => println ("bar") // Case 2
case "both" => println ("foo"); println ("bar")
}
match
执行一个,只有一个,的情况下,所以你不能这样做,因为在比赛的or
。你可以,但是,使用列表和map
/foreach
:
val a = "both"
(a match {
case "both" => List("foo", "bar")
case x => List(x)
}) foreach(_ match {
case "foo" => println("foo")
case "bar" => println("bar")
})
而且您没有复制任何重要的代码(在这种情况下,println
S)。
在被船长明显的风险,在的情况下,像这样,忘记模式匹配并使用if
将是最简单的。
if (a == "both" || a == "foo") println("foo")
if (a == "both" || a == "bar") println("bar")
如果a ==
后顾之忧重复你,你可以不使用的事实,上Set
的apply
方法不一样contains
,是一个有点短写
if (Set("both", "foo")(a)) println("foo")
if (Set("both", "bar")(a)) println("bar")
。
仅有匹配两次:
val a = "both"
a match {
case "both" | "foo" => println ("foo") // Case 1
}
a match {
case "both" | "bar" => println ("bar") // Case 2
}
的
可能重复的[匹配“下通”:执行同一段代码多于一个的情况下(http://*.com/questions/2325863/match-执行同一个代码的情况下,执行多于一种情况) – nawfal