![Scala编程(第4版)](https://wfqqreader-1252317822.image.myqcloud.com/cover/353/38381353/b_38381353.jpg)
5.3 字符串插值
Scala包括了一个灵活的机制来支持字符串插值,允许你在字符串字面量中嵌入表达式。最常见的用途是为字符串拼接提供一个更精简和易读的替代方案。举个例子:
![](https://epubservercos.yuewen.com/E8DF3B/20205397808551606/epubprivate/OEBPS/Images/40272-00-110-1.jpg?sign=1739283146-P9AnRzJlgbfqReg0x3VgeG3fH0oCuUYe-0-430099ba2cc3fc1ca0606ecf233f9b02)
表达式s"Hello, $name!"是一个被处理的(processed)字符串字面量。由于字母s出现在首个双引号前,Scala将使用s这个字符串插值器来处理该字面量。s插值器会对内嵌的每个表达式求值,对求值结果调用toString,替换掉字面量中的那些表达式。因此,s"Hello, $name!"会交出"Hello, reader!",跟"Hello, " + name + "!"的结果一样。
在被处理的字符串字面量中,可以随时用美元符($)开始一个表达式。对于那些单变量的表达式,通常可以在美元符后面直接给出变量的名字。Scala将把从美元符开始到首个非标识符字符的部分作为表达式。如果表达式包含了非标识符字符,就必须将它放在花括号中,左花括号需要紧跟美元符。例如:
![](https://epubservercos.yuewen.com/E8DF3B/20205397808551606/epubprivate/OEBPS/Images/40272-00-110-2.jpg?sign=1739283146-bvwObGdpJN5SppseZhKlQjc5y9IasUu2-0-4cefb2fd8ed2f33fda514f7158b76596)
Scala默认还提供了另外两种字符串插值器:raw和f。raw字符串插值器的行为跟s类似,不过它并不识别字符转义序列(比如表5.2给出的那些)。举例来说,如下语句将打印出四个反斜杠,而不是两个:
![](https://epubservercos.yuewen.com/E8DF3B/20205397808551606/epubprivate/OEBPS/Images/40272-00-110-3.jpg?sign=1739283146-YLK5HDzrcf39UKwkEz19tXxUhGYBkPE1-0-99fd080497e0b68a6e36855f817f4c7d)
f字符串插值器允许你给内嵌的表达式加上printf风格的指令。需要将指令放在表达式之后,以百分号(%)开始,使用java.util.Formatter中给出的语法。比如,可以这样来格式化π:
![](https://epubservercos.yuewen.com/E8DF3B/20205397808551606/epubprivate/OEBPS/Images/40272-00-110-4.jpg?sign=1739283146-kHEXiF8uGiljmMptzgKl47sc3sFq3JaM-0-223c9d9dfa667aeb3df02882bc602acd)
如果不对内嵌表达式给出任何格式化指令,f字符串插值器将默认使用%s,其含义是用toString的值来替换,就像s字符串插值器那样。例如:
![](https://epubservercos.yuewen.com/E8DF3B/20205397808551606/epubprivate/OEBPS/Images/40272-00-111-1.jpg?sign=1739283146-bzCEHafU8DWnbCMLTqYpgk3mjbjQhJhC-0-80506ef0b56a5282cb3ffef3786755ac)
在Scala中,字符串插值是通过在编译期重写代码来实现的。编译器会将任何由——某个标识符紧接着字符串字面量的(左)双引号这样的表达式——当作字符串插值器表达式处理。我们前面看到的字符串插值器s、f和raw,就是通过这个通用的机制实现的。类库作者和用户可以定义其他字符串插值器来满足不同的用途。