1

私は現在、Scala プロジェクトに取り組んでおり、それを Java に変換しています。すべてうまくいっていますが、私はこのスニペットに出くわしました:

    Pattern fileNamePattern = Pattern.compile("^(\\w+).*(_\\w+\\.xml)$");


    new File(filePath).getName match {
        case FileNamePattern(first, last) => return first + last
        case n => return n
    }

正規表現、1 つ以上の文字、数字、または句読点の後に 0 つ以上の文字が続き、その後に 1 つ以上の文字、数字、または句読点が続くことを理解しています。この関数の目的は、ファイル パスからファイル名を取得することですが、これは Java では非常に単純なので、Scala 開発者が必要以上に複雑にすることはないと思います。

問題は、開発者がもう少し賢いことをしようとしているのに、開発者がばかだと思い込んで前に進みたくないということです。Scala の経験が不足しているため、それを見ることができません。誰かが説明してください:

  • match を使用した構文
  • 地獄の最初と最後はどこから来たのか
  • このスニペットに相当する Java に相当する / ドキュメント
def getFileName(filePath: String): String = {

    if(filePath == null || filePath.trim.length == 0) {
      return filePath
    }

    val FileNamePattern = new Regex("^(\\w+).*(_\\w+\\.xml)$")

    new File(filePath).getName match {
         case FileNamePattern(first, last) => return first + last
         case n => return n
    }
}
4

1 に答える 1

3

コンストラクトは、matchパターン マッチングを行うために使用されます。基本的に、 の左側matchは、右側にあるパターンと照合するオブジェクトです。生成されたコードは各パターンを出現順にテストし、パターンがオブジェクトと一致する場合は、 の後のコード=>が実行されます。

式内のfirstおよびlast変数はmatch、パターン マッチング機構によってバインドされる変数であり、それらが出現するパターンがオブジェクトと一致する場合に使用されます。それらの値は、一致するオブジェクト グラフの対応する値になります。言い換えれば、それらはパターンによって暗黙的に宣言され、 の後の「結果」節で適切に初期化されます=>

古典的な例:

trait Expr

case class Const(val value: Int) extends Expr
case class Add(val left: Expr, val right: Expr) extends Expr

def evaluate(exp: Expr): Int = exp match {
    case Const(cv) => cv
    case Add(exp1, exp2) => evaluate(exp1) + evaluate(exp2)
    case _ => throw new IllegalArgumentException("did not understand: " + exp)
}

unapplyScala の正規表現オブジェクトは、( /unapplySeqメソッドを介して) パターン マッチングを特別にサポートしています。この場合、正規表現が によって返される文字列と一致する場合getName、変数firstlastはそれぞれ正規表現の最初のサブグループと 2 番目のサブグループに一致する部分文字列にバインドされます。

Java にはmatch類似の言語構造がありません。同等の Java コードは、かなり長くて面倒です。次のように見えるかもしれません

final String name = (new File(filePath).getName());
final Matcher matcher = FileNamePattern.match(name);

if (matcher.matches()) {

    final String first = matcher.group(1);
    final String last = matcher.group(2);
    return first + last;

} else {

    return name;
}
于 2013-08-07T11:10:32.270 に答える