2011-08-16 7 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") 

これは、ターゲットが実際に入力されたものに割り当てたい名前だと思うからです。 2つの質問:

  1. この現象はなぜですか?適切な型を持つ既存の変数をスコープ内で探し、見つからなければpatternmatchの名前としてtargetを扱うことはできません。

  2. 回避策はありますか?変数とパターンマッチングする方法はありますか?最終的に大きなif文を使用できますが、大文字小文字の区別はよりエレガントです。

+0

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

+0

私はこの質問、コード、および回答がScala 2.12.xでは時代遅れであると信じています。問題の一部として、適用されるバージョンが言及されていれば、うれしいでしょう。 – conny

答えて

181

あなたが探しているのは安定した識別子です。 Scalaでは、これらは大文字で始まるか、またはバッククォートで囲まなければなりません。

これらのいずれもが、あなたの問題への解決策のようになります。

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

関連する問題