Scala:字符串 “+” vs “++”
我是Scala的新手,我已经看到过在Scala中连接字符串的代码,如下所示:
"test " ++ "1"
我已经测试过了,它也用Scala Doc编写。
"test " + "1"
所以我的理解是,这就像Java字符串一样,但功能更强大,可以接受更多类型的参数。似乎对其他事情(如List)也很普遍。我想知道我的理解是否正确。和任何其他差异?什么时候应该为了字符串串联而超越另一个?+
+
++
++
我是Scala的新手,我已经看到过在Scala中连接字符串的代码,如下所示:
"test " ++ "1"
我已经测试过了,它也用Scala Doc编写。
"test " + "1"
所以我的理解是,这就像Java字符串一样,但功能更强大,可以接受更多类型的参数。似乎对其他事情(如List)也很普遍。我想知道我的理解是否正确。和任何其他差异?什么时候应该为了字符串串联而超越另一个?+
+
++
++
它有助于看一下scala。预先确定
到底发生了什么。
如果你检查那里,你会看到在Scala中只是的别名。换句话说,a 上的方法被转换为 Java 的运算符。String
java.lang.String
+
String
+
所以,如果 Scala 只是一个 Java ,那么这个方法怎么存在,你可能会问。(好吧,至少我会问。答案是,该方法提供了从 到 的隐式转换,该方法也在 .String
String
++
String
WrappedString
wrapString
Predef
请注意,采用任何实例并将该实例中的所有元素添加到原始 。(请注意,文档错误地指出该方法返回 .这必须是不正确的,因为不采用类型参数。你会得到的是一个(如果你添加的东西是一个)或一些(如果不是)。++
GenTraversableOnce
WrappedString
WrappedString[B]
WrappedString
String
Seq[Char]
IndexedSeq[Any]
以下是一些示例:
如果将 a 添加到 中,则会得到一个字符串。String
List[Char]
scala> "a" ++ List('b', 'c', 'd')
res0: String = abcd
如果将 a 添加到 ,则得到一个 .实际上,前两个元素是 s,但后三个是 s,如后续调用所示。String
List[String]
IndexedSeq[Any]
Char
String
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 的复杂方法,它给你一个 .String
String
++
String
WrappedString
IndexedSeq[Char]
Seq[Char]
Seq[Char]
Seq[Char]
scala> "abc" + "def"
res0: String = abcdef
正如Alexey所指出的,这些都不是一个非常微妙的工具,所以你最好使用字符串插值或StringBuilder
,除非有充分的理由不这样做。
String
是一个,这意味着它可以分解成一系列元素(字符)。这就是从哪里来的,否则你不能在String上做。 仅当它的右侧(或该函数的参数)是可解组合类型(或可遍历类型)时才有效。TraversableLike
++
++
++
现在如何成为?在这里,定义的隐式开始发挥作用。其中一个隐式将 normal 转换为一个 where,它具有基本上以这种方式工作的所有胶水:String
TraversableLike
Predef
String
WrappedString
WrappedString.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"
这更具可读性。
更多详情: