Pomaga spojrzeć w scala.Predef
aby zobaczyć, co dokładnie się dzieje.
Jeśli to zrobisz, zobaczysz, że String
w Scali to tylko alias dla java.lang.String
.Innymi słowy, metoda +
na String
zostaje przetłumaczona na operatora Javy +
.
Tak więc, jeśli Scala String
to tylko Java String
, jak może istnieć metoda ++
, możesz zapytać. (Cóż, chciałbym zapytać, przynajmniej.) Odpowiedź jest taka, że istnieje niejawna konwersja z String
do WrappedString
dostarczona przez metodę wrapString
, która jest również w Predef
.
Zauważ, że ++
pobiera dowolną instancję GenTraversableOnce
i dodaje wszystkie elementy w tej instancji do oryginalnego WrappedString
. (Zauważ, że dokumenty niepoprawnie informują, że metoda zwraca wartość WrappedString[B]
. To musi być niepoprawne, ponieważ WrappedString
nie przyjmuje parametrów typu.) To, co otrzymasz, to albo String
(jeśli rzecz, którą dodasz, to Seq[Char]
) lub trochę IndexedSeq[Any]
(jeśli nie jest).
Oto kilka przykładów:
Jeśli dodać String
Do List[Char]
, masz String.
scala> "a" ++ List('b', 'c', 'd')
res0: String = abcd
Jeśli dodać String
Do List[String]
, masz IndexedSeq[Any]
. W rzeczywistości pierwsze dwa elementy to Char
s, ale ostatnie trzy to String
s, jak pokazuje to kolejne połączenie.
scala> "ab" ++ List("c", "d", "e")
res0: scala.collection.immutable.IndexedSeq[Any] = Vector(a, b, c, d, e)
scala> res0 map ((x: Any) => x.getClass.getSimpleName)
res1: scala.collection.immutable.IndexedSeq[String] = Vector(Character, Character, String, String, String)
Wreszcie, jeśli dodać do String
String
z ++
, wrócisz do String
. Powodem tego jest fakt, że WrappedString
dziedziczy po IndexedSeq[Char]
, więc jest to zawiły sposób dodawania Seq[Char]
do Seq[Char]
, który daje ci powrót do Seq[Char]
.
scala> "abc" + "def"
res0: String = abcdef
Jak zauważył Alexey, żadna z nich nie jest bardzo subtelne narzędzie, więc jesteś prawdopodobnie lepiej wyłączyć za pomocą string interpolation lub StringBuilder
chyba nie jest dobry powód, aby nie.
Poza odpowiedziami, polecam, aby nie używać '+' dłużej. Najprawdopodobniej zostanie wycofany i ostatecznie usunięty. Teraz Scala ma interpolację ciągów, która jest preferowanym sposobem komponowania ciągów. Używanie '++' może być wolniejsze, ale myślę, że jest to dobra alternatywa, syntaktycznie czysta i zgodna z kolekcjami Scali. –
@ 0__ 2 godziny temu, + jest z ciągu znaków Java prawda? Chodzi mi o to, czy Scala zachowałaby go dla ciągów Scala? –
'+' nie jest zdefiniowane w API 'java.lang.String', w Javie jest to po prostu syntaktyczny cukier do uruchamiania kreatora stringów. To samo dotyczy Scala, gdzie łańcuchowanie z '+' jest definiowane przez kompilator nawet w przypadku braku 'Predef.any2stringadd'. Zobacz także: https://stackoverflow.com/questions/2664274/how-to-unimport-string-operator-in-scala –