4

私はちょうど Scala を学んでいるので、これがすでに議論されている場合は申し訳ありませんが、次のことは私には少し奇妙に思えました:

scala> import scala.collection.immutable._
import scala.collection.immutable._

scala> val st1 = new WrappedString("Hello")
st1: scala.collection.immutable.WrappedString = Hello

scala> val st2 = new StringOps("Hello")
st2: scala.collection.immutable.StringOps = Hello

scala> st2 == st1
res0: Boolean = true

scala> st1 == st2
res1: Boolean = false

誰でもこれを説明できますか?Scala バージョン 2.10.0-M4 を使用しています。他のバージョンでこれを試したことはありません。

4

1 に答える 1

7

違いが生じる理由は 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]

于 2012-06-17T10:11:46.610 に答える