SCALA 字符串插值
字符串插值提供了一种在字符串内部使用变量的方法。例如:
val name = "James"
val age = 30
println(s"$name is $age years old") // "James is 30 years old"
使用字符串插值需要在字符串引号前加上s
,并在任何变量名前加上$
符号。
其他插值器
你放在字符串前面的s
只是Scala提供的一种可能的插值器之一。
Scala提供了三种默认的字符串插值方法:s、f和raw。此外,字符串插值器只是一种特殊的方法,因此也可以定义自己的插值器。例如,某些数据库库定义了一个返回数据库查询的sql插值器。
s插值器(s-Strings)
将s
添加到任何字符串字面量前允许直接在字符串中使用变量。你已经在这里看到了一个例子:
val name = "James"
val age = 30
println(s"$name is $age years old") // "James is 30 years old"
在这个例子中,字符串中的$name
和$age
占位符分别被替换为调用name.toString
和age.toString
的结果。s-String将可以访问当前范围内的所有变量。
虽然这似乎是显而易见的,但重要的是要注意,在普通的字符串字面量中不会发生字符串插值:
val name = "James"
val age = 30
println("$name is $age years old") // "$name is $age years old"
字符串插值器还可以接受任意表达式。例如:
println(s"2 + 2 = ${2 + 2}") // "2 + 2 = 4"
val x = -1
println(s"x.abs = ${x.abs}") // "x.abs = 1"
任何任意的表达式都可以嵌入${}
中。
对于某些特殊字符,在字符串中嵌入时需要对它们进行转义。要表示实际的美元符号,可以使用两个$$
,如下所示:
println(s"New offers starting at $$14.99") // "New offers starting at $14.99"
双引号也需要转义。可以使用三个双引号来实现:
println(s"""{"name":"James"}""") // `{"name":"James"}`
最后,所有多行字符串字面量也可以插值:
println(s"""name: "$name",
|age: $age""".stripMargin)
输出结果如下:
name: "James"
age: 30
f插值器(f-Strings)
将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"
^
val height: Double = 1.9d
scala> f"$height%4d"
-- Error: ----------------------------------------------------------------------
1 |f"$height%4d"
| ^^^^^^
| Found: (height : Double), Required: Int, Long, Byte, Short, BigInt
1 error found
f
插值器利用了Java中提供的字符串格式化工具。在%字符后允许的格式在Formatter javadoc中有详细介绍。如果在变量定义后没有%字符,则假定为%s(字符串)的格式。
最后,和Java一样,使用%%
可以在输出字符串中获得一个字面上的%字符:
println(f"3/19 is less than 20%%") // "3/19 is less than 20%"
raw插值器
raw插值器类似于s插值器,只是它不对字符串中的字面量进行转义。下面是一个处理后的示例字符串:
scala> s"a\nb"
res0: String =
a
b
这里,s字符串插值器将字符\n
替换为回车字符。而raw插值器则不会这样做:
scala> raw"a\nb"
res1: String = a\nb
当你想避免像\n
这样的表达式变成回车字符时,raw插值器很有用。
除了三个默认的字符串插值器外,用户还可以定义自己的插值器。
**参考链接:**https://docs.scala-lang.org/scala3/book/string-interpolation.html