Scala中的String类使用的就是Java的String.class;所以,用法跟Java相同。但是Scala中加入了StringOps类扩展了String,有一些很有用的方法。
几个需要注意的是:
"a" * 2 返回:"aa":字符串 * 2。
""" She said: "Hey,geys." And then... """:原生字符串,其中可有任意符号。
官方文档:String Interpolation
从 Scala2.10.0 开始,Scala提供一个新的机制,通过你的数据创建字符串:字符串插值(String Interpolation)。它允许用户将变量的引用直接嵌入到处理字符串字面量(processed string literals)中。例如:
val name = "James" println(s"Hello, $name") // Hello, Jameshttp://write.blog.csdn.net/postedit/44498133
上文中, s"Hello, $name"是会被 s 处理的字符串字面量,这意味着编译器会对这个字面量做一些额外的工作。 s 处理字符串字面量表示为一个在"(双引号)之前的字符集合。
Scala提供了三个开箱即用的字符串插入方法: s, f和 raw。
预先准备s可以在任意的字符串字面量中直接使用变量。例如:
val name = "James" println(s"Hello, $name") // Hello, James
这里 $name
是个嵌入在 s 处理的字符串。s插值器知道字符串中变量 name的值,返回 Hello, James。
字符串插值器也可以包含任意表达式(通过${})。例如:
println(s"1 + 1 = ${1 + 1}")
在任何字符串字面量前追加f,就可以创造一个简单的格式化字符串,类似于其他语言中的printf。当使用插值器f时,所有变量的引用应该跟随printf风格的格式字符串,如同 %d。来看一个例子:
val height = 1.9d val name = "James" println(f"$name%s is $height%2.2f meters tall") // James is 1.90 meters tall
插值器f是类型安全的。如果你试图传递一个只能工作于整数的格式化字符串,却又传了一个浮点数,编译器会发出一个错误。例如:
val height: Double = 1.9d scala> f"$height%4d" <console>:9: error: type mismatch; found : Double required: Int f"$height%4d" ^
插值器f利用Java的字符串格式工具(The f interpolator makes use of the string format utilities available from Java.)。字符%后允许的格式在Formatter javadoc中有概述。如果一个变量没有定义格式器,那么就假设它是%s(String)(即f"$name"等同于f"$name%s")。
插值器raw和插值器s相似,不同的是它不对字符串字面量执行转义。这有一个例子:
scala> s"a\nb" res0: String = a b
插值器s将字符\n替换成了回车符。而插值器raw不会这么做。
scala> raw"a\nb" res1: String = a\nb
当你想要避免有表达式(例如\n变成回车)时,插值器raw是很有用的。
在Scala中,所有处理字符串字面量都是简单的代码转换。每当编译器遇到如下形式的字符串字面量:
id"string content"
编译器把它转换成StringContext实例的一个方法调用(id)。这个方法也可以在隐式作用域内。要定义自己的字符串插值,我们需要简单地创建一个隐式类并且添加一个新方法到StringContext。这有一个例子:
<code class="scala comments">// Note: We extends AnyVal to prevent runtime instantiation. See</code><div class="container"><div class="line number2 index1 alt1"><code class="scala comments">// value class guide for more info.</code></div><div class="line number3 index2 alt2"><code class="scala keyword">implicit</code> <code class="scala keyword">class</code> <code class="scala plain">JsonHelper(</code><code class="scala keyword">val</code> <code class="scala plain">sc</code><code class="scala keyword">:</code> <code class="scala plain">StringContext) </code><code class="scala keyword">extends</code> <code class="scala plain">AnyVal {</code></div><div class="line number4 index3 alt1"><code class="scala spaces"> </code><code class="scala keyword">def</code> <code class="scala plain">json(args</code><code class="scala keyword">:</code> <code class="scala plain">Any*)</code><code class="scala keyword">:</code> <code class="scala plain">JSONObject </code><code class="scala keyword">=</code> <code class="scala plain">sys.error(</code><code class="scala string">"TODO - IMPLEMENT"</code><code class="scala plain">)</code></div><div class="line number5 index4 alt2"><code class="scala plain">}</code></div><div class="line number6 index5 alt1"><code class="scala keyword">def</code> <code class="scala plain">giveMeSomeJson(x</code><code class="scala keyword">:</code> <code class="scala plain">JSONObject)</code><code class="scala keyword">:</code> <code class="scala plain">Unit </code><code class="scala keyword">=</code> <code class="scala plain">...</code></div><div class="line number7 index6 alt2"><code class="scala plain">giveMeSomeJson(json</code><code class="scala string">"{ name: $name, id: $id }"</code><code class="scala plain">)</code></div></div>
(呃...这里包含了隐式类和值类,都是Scala2.10的新特性。稍后可能会把这两个特性也翻译一下——如果看得懂的话。另外,implicit只能声明内部类,否则会报错,这点还不确认,等看完隐式类再说。)
在这个例子中,我们试图使用字符串插值创建一个JSON文字语法。隐式类JsonHelper必需在作用域内才可以使用这个语法,并且json方法需要完整地实现。无论如何,这个格式化字符串的结果将不是一个字符串,而是JSONObject。
当编译器遇到字符串json"{ name: $name, id: $id }",它将字符串重写为如下表达式:
new StringContext("{ name:", ",id: ", "}").json(name, id)
然后隐式类用于将它重写成如下形式:
new JsonHelper(new StringContext("{ name:", ",id: ", "}")).json(name, id)
这样,json方法可以访问原始块字符串,并将每一个表达式作为值。一个简单的方法实现可以是:
implicit class JsonHelper(val sc: StringContext) extends AnyVal { def json(args: Any*): JSONObject = { val strings = sc.parts.iterator val expressions = args.iterator var buf = new StringBuffer(strings.next) while(strings.hasNext) { buf append expressions.next buf append strings.next } parseJson(buf) } }
处理后的字符串中的每一部分都暴露在StringContext的parts成员中。每个表达式的值被传递给json方法的args参数。json方法得到它并产生一个很大的字符串,然后将其解析成JSON。一个更复杂的实现,可以避免生成这个字符串,并简单地从原始字符串和表达式的值直接构造JSON对象。
字符串插值目前无法工作在模式匹配语句中。此功能是针对Scala的2.11版本。