違いが生じる理由は ScalaDoc に記載されています。
ラップされた文字列:
このクラス と の違いは、やStringOpsなどの変換メソッドを呼び出すと、 ではなく型のオブジェクトが生成されることです。filtermapWrappedStringString
StringOps:
このクラス と の違いは、やWrappedStringなどの変換メソッドを呼び出すとfilterオブジェクトmapが生成されるのString
に対し、WrappedStringは のままであるということWrappedStringです。
collection.GenSeqLikeどちらもequals メソッドを定義する派生元です。
override def equals(that: Any): Boolean = that match {
case that: GenSeq[_] => (that canEqual this) && (this sameElements that)
case _ => false
}
両方とも、常に true を返すcanEqual(から派生したcollection.IterableLike) を実装します。しかし、ではありません:StringOpscollection.GenIterable
scala> st1 sameElements st2
<console>:13: error: type mismatch;
found : scala.collection.immutable.StringOps
required: scala.collection.GenIterable[?]
st1 sameElements st2
^
一方WrappedString、:
scala> st2 sameElements st1
res13: Boolean = true
trueしたがって、最初のケースが返され、もう 1 つのケースが返される理由は明らかfalseです。
しかし、なぜ両方が存在するのでしょうか。なぜこのように設計されているのかはよくわかりませんが、Scala では String がコレクションではないためだと思います。"abc" flatMap (_+"z")に示すように、常に可能であるとは限りませんが、別の文字列を取得したいような文字列に対して何らかの操作を行う場合"abc" map (_+1)。これが何をするかStringOpsです。しかし、何らかのメソッドがある場合def x[A](s: Seq[A]) = s.getClass、文字列でどのように呼び出すのでしょうか? この場合、次のものが必要ですWrappedString。
scala> x("a")
res9: Class[_ <: Seq[Char]] = class scala.collection.immutable.WrappedString
だから、StringOpsより軽量WrappedStringです。java.lang.Stringこれにより、オーバーヘッドをあまりかけずに、plain old でいくつかのメソッドを呼び出すことができます。2.10 ではStringOps拡張しAnyValます。これは、それが値クラスであり、その存在が scalac によって最適化できることを意味します (文字列をラップすることにより、実行時のオーバーヘッドがなくなります)。対照的WrappedStringに、 String を実際のコレクションとして、つまり として扱うことができますIndexedSeq[Char]。