2.4 字符串的变量代入

问题

你想在一个字符串中使用变量替换,就像使用Perl、PHP和Ruby时一样。

解决方案

要在Scala中使用基本的字符串插值,需要在字符串前加上字母s,并在字符串中包含需要替换的变量,变量名称前面需要加上字符$,参照下面的println语句:

根据Scala官方的字符串插值文档(https://oreil.ly/A3hqn),当在字符串前面加上字母s时,就是在创建一个经过处理的字符串字面量。这个例子使用了“ s字符串插值器”,它可以让你在字符串中嵌入变量,这些变量将被它们的值取代。

在字符串字面量中使用表达式

除了把简单的变量放在字符串中,还可以将表达式放在字符串的大括号里,在下面的例子中,会把age加1后的结果放到字符串中:

下面这个例子展示了在大括号中使用相等判断:

在输出对象字段时也需要使用大括号:

注意,如果输出对象字段时不使用大括号,输出的信息会与预期不符:

讨论

放在字符串前面的s实际上是一个方法。虽然这似乎比直接把变量放在字符串里不那么方便,但这么做至少有两个好处:

·Scala提供了其他插值函数,这让你有更多的掌控力。

·任何人都可以定义自己的字符串插值函数。例如,Scala的SQL库就利用了这种能力,可以写出像sql"SELECT * FROM USERS"的查询。

我们来看看另外两个Scala内置的插值函数。

f字符串插值器(printf风格的格式化)

在前面解决方案的例子中,weight的值输出为200.0。这完全正确,但如果想多输出几位小数,或者完全删除它们,该怎么做呢?

这个简单的需求催生了“f字符串插值器”,一个可以通过printf格式化内部字符串的方法。接下来的例子会说明如何输出保留两位小数的weight:

还会说明如何打印不保留小数的weight:

如上所述,要使用这种方法,只需要做到如下两步:

·在字符串前加f。

·在变量后使用printf风格的格式化指定符。

printf格式化指定符

最常用的printf格式化指定符会在2.5节中列举。

虽然这些例子使用了println方法,但需要注意的是,完全可以将变量替换的结果赋给一个新的变量,类似于在其他语言中使用sprintf:

现在s只是一个普通的字符串,可以用在任何需要字符串的地方。

raw插值器

除了s和f字符串插值器之外,Scala还包含另一个叫作raw的插值器。使用raw插值器不会对字符串里的任何转义字符进行转义。下面这个例子是对raw与s插值器进行比较:

如上所示,s会对\n转义成换行符,而raw不对其做任何转义,只是将其当作普通字符处理。

创建自定义插值器

除了s、f和raw插值器,还可以定义自己的插值器。2.11节将给出创建自定义插值器的例子。

另见

·2.5节将列举许多常用的字符串格式化的字符。

·Oracle Formatter类文档(https://oreil.ly/gEAsi)有一个完整的、可以使用的格式化字符的列表。

·Scala官方字符串插值页面(https://oreil.ly/A3hqn)有更多关于插值器的细节。

·2.11节将给出创建自定义插值器的例子。