11

Scala では、文字列を Seq[Char] として扱うことにより、文字列の個々の文字に基づいてパターンを定式化することができます。

この機能の例は、A Tour of Scalaに記載されています。

これはそこで使用されるコード例です:

object RegExpTest1 extends Application {
 def containsScala(x: String): Boolean = {
   val z: Seq[Char] = x
   z match {
      case Seq('s','c','a','l','a', rest @ _*) =>
                println("rest is "+rest)
                true
      case Seq(_*) =>
                false
   }
 }

}

これに関する問題は、スニペットの 3 行目です。

val z: Seq[Char] = x

なぜこの種のキャストが必要なのですか?String は、すべての状況 (パターン マッチングを含む) で Seq[Char] のように振る舞うべきではありませんか? ただし、この変換がないと、コード スニペットは機能しません。

4

3 に答える 3

19

質問とコメントでは、用語の実際の乱用が行われています。このコードにはキャストはありません。特に、「基本的に、これは Java の相互運用性に対する大きな譲歩であり、型の健全性を犠牲にしています」というのは実際には何の根拠もありません。

スカラ キャストは次のようになりますx.asInstanceOf[Y]
上に表示されているのは割り当てです。val z: Seq[Char] = x

Stringからへの暗黙の変換があるため、この代入は有効ですSeq[Char]。繰り返しますが、これはキャストではありません。キャストは、実行時に失敗する可能性がある任意のアサーションです。暗黙的な変換が失敗することはありません。

型間の暗黙的な変換に依存することの問題、および元の質問への答えは、元の値が型チェックを行わない場合にのみ暗黙的な変換が行われることです。文字列での一致は完全に合法であるため、変換は行われず、一致は失敗します。

于 2009-04-12T00:01:04.153 に答える
12

これが正しいかどうかは 100% 確信が持てませんが、私の直感では、この明示的なキャストがなければ、 に対してパターン マッチを行うことjava.lang.Stringになり、これは望んでいるものではありません。

Predef.stringWrapper明示的なキャストは、Scala コンパイラに暗黙の変換を強制的に使用させます。したがって、RichString extendsSeq[Char]のように、文字列が一連の文字であるかのようにパターン マッチを行うことができます。

于 2009-04-11T18:25:48.763 に答える
7

アンドリが言ったことをすべてエコーします。相互運用性のために、Scala文字列はjava.lang.Stringsです。には、を実装するからへPredefの暗黙の変換があります。StringRichStringSeq[Char]

zを保持するための中間値を必要とせずに、パターンマッチをコーディングするためのおそらくより良い方法Seq[Char]

def containsScala(x: String): Boolean = {
  (x: Seq[Char]) match {
    ...
  }
}
于 2009-04-11T21:05:26.900 に答える