2011-08-16 86 views
91

看看下面的功能:爲什麼Scala中的模式匹配不適用於變量?

def fMatch(s: String) = { 
    s match { 
     case "a" => println("It was a") 
     case _ => println("It was something else") 
    } 
} 

這種模式很好地匹配:

scala> fMatch("a") 
It was a 

scala> fMatch("b") 
It was something else 

我想做什麼就能做的是以下幾點:

def mMatch(s: String) = { 
    val target: String = "a" 
    s match { 
     case target => println("It was" + target) 
     case _ => println("It was something else") 
     } 
} 

這散發出以下錯誤:

fMatch: (s: String)Unit 
<console>:12: error: unreachable code 
       case _ => println("It was something else") 

我想這是因爲它認爲目標實際上是您想要分配給任何輸入的名稱。兩個問題:

  1. 爲什麼會這樣?不能僅僅查找範圍中具有適當類型的現有變量並首先使用它們,如果沒有找到,然後將目標作爲模式匹配的名稱來處理?

  2. 有沒有解決方法?任何模式匹配變量的方式?最終可以使用大的if語句,但是匹配大小更優雅。

+0

相關:http://stackoverflow.com/questions/7083502/why-cant-a-variable-be-a-stable-identifier –

+0

我相信這個問題,代碼和答案是過時的斯卡拉2.12.x.如果適用的版本被作爲問題的一部分提及,那將會很好。 – conny

回答

181

你在找什麼是穩定標識符。在斯卡拉,這些必須以大寫字母開頭,或者用反引號包圍。

這兩個將是你的問題的解決方案:

def mMatch(s: String) = { 
    val target: String = "a" 
    s match { 
     case `target` => println("It was" + target) 
     case _ => println("It was something else") 
    } 
} 

def mMatch2(s: String) = { 
    val Target: String = "a" 
    s match { 
     case Target => println("It was" + Target) 
     case _ => println("It was something else") 
    } 
} 

爲了避免意外指的是已在封閉的範圍存在變數,我覺得很有道理,默認行爲是小寫模式是變量而不是穩定的標識符。只有當你看到以大寫字母開頭的東西或者後面的蜱時,你是否需要意識到它來自周圍的範圍。

+2

我敢打賭,這來自Erlang,其中變量以大寫字母和小寫符號開頭。 –

+9

注意'target'是一個值('val'),而不是一個變量('var')。它不適用於變量。 –

+0

大寫? FORTRAN的色調。弱,馬丁,弱。 – Malvolio