Scala:字符串 “+” vs “++”

2022-09-04 07:35:10

我是Scala的新手,我已经看到过在Scala中连接字符串的代码,如下所示:

"test " ++ "1"

我已经测试过了,它也用Scala Doc编写。

"test " + "1"

所以我的理解是,这就像Java字符串一样,但功能更强大,可以接受更多类型的参数。似乎对其他事情(如List)也很普遍。我想知道我的理解是否正确。和任何其他差异?什么时候应该为了字符串串联而超越另一个?++++++


答案 1

它有助于看一下scala。预先确定到底发生了什么。

如果你检查那里,你会看到在Scala中只是的别名。换句话说,a 上的方法被转换为 Java 的运算符。Stringjava.lang.String+String+

所以,如果 Scala 只是一个 Java ,那么这个方法怎么存在,你可能会问。(好吧,至少我会问。答案是,该方法提供了从 到 的隐式转换,该方法也在 .StringString++StringWrappedStringwrapStringPredef

请注意,采用任何实例并将该实例中的所有元素添加到原始 。(请注意,文档错误地指出该方法返回 .这必须是不正确的,因为不采用类型参数。你会得到的是一个(如果你添加的东西是一个)或一些(如果不是)。++GenTraversableOnceWrappedStringWrappedString[B]WrappedStringStringSeq[Char]IndexedSeq[Any]

以下是一些示例:

如果将 a 添加到 中,则会得到一个字符串。StringList[Char]

scala> "a" ++ List('b', 'c', 'd')
res0: String = abcd

如果将 a 添加到 ,则得到一个 .实际上,前两个元素是 s,但后三个是 s,如后续调用所示。StringList[String]IndexedSeq[Any]CharString

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)

最后,如果将 a 添加到 with 中,则返回一个 .这样做的原因是 继承自 ,所以这是一种将 a 添加到 a 的复杂方法,它给你一个 .StringString++StringWrappedStringIndexedSeq[Char]Seq[Char]Seq[Char]Seq[Char]

scala> "abc" + "def"
res0: String = abcdef

正如Alexey所指出的,这些都不是一个非常微妙的工具,所以你最好使用字符串插值StringBuilder,除非有充分的理由不这样做。


答案 2

String是一个,这意味着它可以分解成一系列元素(字符)。这就是从哪里来的,否则你不能在String上做。 仅当它的右侧(或该函数的参数)是可解组合类型(或可遍历类型)时才有效。TraversableLike++++++

现在如何成为?在这里,定义的隐式开始发挥作用。其中一个隐式将 normal 转换为一个 where,它具有基本上以这种方式工作的所有胶水:StringTraversableLikePredefStringWrappedStringWrappedString.canBuildFrom

WrappedString.canBuildFrom -> StringBuilder -> StringLike -> IndexedSeqOptimized -> IndexedSeqLike -> SeqLike -> IterableLike -> TraversableLike

由于 Predef 中定义的隐式已经在作用域中,因此可以编写如下代码:

"test " ++ "1"

现在您的问题:

我想知道我的理解是否正确。和任何其他差异?

是的,您的理解是正确的方向。

什么时候应该为了字符串串联而超越另一个?

对于字符串串联,显然创建的对象更少,函数调用次数更少。但是,我总是更喜欢像这样进行字符串插值:"test " + "1"

val t1 = "test"
val t2 = "1"
val t3 = s"$t1 $t2"

这更具可读性。

更多详情: