Scala のパターン マッチングが変数では機能しないのはなぜですか? 質問する

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. なぜこのような動作になるのでしょうか? 適切な型を持つスコープ内の既存の変数を検索して最初に使用し、見つからない場合はターゲットをパターンマッチする名前として扱うことはできないのでしょうか?

  2. これを回避する方法はありますか? 変数に対してパターン マッチを行う方法はありますか? 最終的には大きな if ステートメントを使用することもできますが、match case の方がエレガントです。

ベストアンサー1

あなたが探しているのは安定した識別子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")
    }
}

囲んでいるスコープ内に既に存在する変数を誤って参照することを避けるために、小文字のパターンを固定の識別子ではなく変数にするというデフォルトの動作は理にかなっていると思います。大文字で始まるものやバックティックで始まるものを見つけた場合にのみ、それが周囲のスコープからのものであることを認識する必要があります。

おすすめ記事