2009-04-11 24 views
10

Scalaでは、文字列の非正規文字に基づくパターンをSeq [Char]として扱うことができます。文字列に一致するパターンSeq [Char]

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行目である:

この機能の例は、これが使用される例のコードであるA Tour of Scala

に記載されています:

val z: Seq[Char] = x 

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

答えて

11

これが正しければ100%ではありませんが、この明示的なキャストがなければ、java.lang.Stringとのパターンマッチはあなたが望むものではないと私の直感は言っています。

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

+0

これはかなり意味があり、基本的に私が推測していたものです。しかし、暗黙のコンバータは見つかりませんでした。それを指摘してくれてありがとう。 基本的に、これはJavaの相互運用性に対する大きな譲歩であり、いくつかのタイプの健全性を犠牲にしています。 –

+2

タイプの健全性が失われません。暗黙の変換は、関数呼び出しをコンパイラに挿入するだけです。val:Seq [Char] = string2Seq(x) –

7

私はアンリが言ったことすべてをエコーするつもりです。相互運用性のために、スカラ文字列はjava.lang.Stringです。 PredefにはStringからRichStringへの暗黙的な変換があり、これはSeq[Char]を実装しています。

A Seq[Char]を保持するために、中間のval zを必要とせずに、パターンマッチを符号化する、おそらくよりよい方法:

def containsScala(x: String): Boolean = { 
    (x: Seq[Char]) match { 
    ... 
    } 
} 
17

質問やコメントで起こっている用語のいくつかの実際の乱用があります。このコードにはキャストはなく、特に「基本的に、これはJavaの相互運用性に対する大きな譲歩であり、いくつかの型の健全性を犠牲にする」は、実際には根拠がない。

スカラキャストはx.asInstanceOf[Y]のようになります。あなたは上記を参照何
は割り当てです:val z: Seq[Char] = x

StringからSeq[Char]への暗黙的な変換があるので、この割り当ては合法です。私は再び強調します、これはキャストではありません。キャストは実行時に失敗する任意のアサーションです。暗黙の変換が失敗する方法はありません。

タイプ間の暗黙的な変換と元の質問への回答に依存する問題は、元の値がタイプチェックを行わない場合にのみ暗黙の変換が行われることです。 String上でマッチすることは完全に合法であるため、変換は行われません。マッチはただ失敗します。

+1

Stringは、Java型のtypedefであるため、Seq [Char]から継承できません。 –

+2

申し訳ありませんが、種類の譲歩があることは間違いありません(実際にはスカラーはそれらと泳いでいます)。 – extempore

関連する問題