請考慮以下Scala代碼。與多個匹配匹配的模式
val a = "both"
a match {
case "both" | "foo" => println ("foo") // case 1
case "both" | "bar" => println ("bar") // case 2
}
我想match
工作,所以,如果a == "both"
,斯卡拉將執行兩種情況。這是可能的還是有其他方法可以實現我想要的?
請考慮以下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://stackoverflow.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://stackoverflow.com/questions/2325863/match-執行同一個代碼的情況下,執行多於一種情況) – nawfal