Scala 字符串
在 Scala 中,字符串(String)是一种常用的数据类型,用于表示文本数据。Scala 的字符串基于 Java 的 java.lang.String
类,因此与 Java 字符串高度兼容,同时 Scala 提供了更强大的功能,如字符串插值和多行字符串。以下是对 Scala 字符串的中文讲解,内容简洁清晰,涵盖定义、操作、插值、多行字符串及注意事项,适合初学者理解。
1. 字符串概述
- 定义:字符串是由字符序列组成的对象,表示为
String
类型,存储在 JVM 的字符串常量池中。 - 特点:
- 不可变(Immutable):字符串内容一旦创建不可更改,任何修改都会生成新字符串。
- 基于 Java:继承了 Java 的
String
类功能,同时支持 Scala 的函数式特性。 - 支持字符串插值(interpolation)和多行字符串,简化文本处理。
- 用途:用于文本处理、数据格式化、文件操作等。
2. 字符串的定义
字符串字面量用双引号 ""
包裹,支持类型推断:
val str: String = "Hello, Scala" // 显式类型
val greeting = "Hello, Scala" // 类型推断
println(greeting) // 输出: Hello, Scala
3. 字符串操作
Scala 字符串继承了 Java 的方法,同时支持 Scala 的函数式操作。以下是常见操作:
1. 基本操作
- 长度:
length
方法返回字符串长度。
val str = "Scala"
println(str.length) // 输出: 5
- 连接:使用
+
或concat
连接字符串。
val s1 = "Hello"
val s2 = "Scala"
println(s1 + ", " + s2) // 输出: Hello, Scala
println(s1.concat(", ").concat(s2)) // 同上
- 访问字符:通过索引访问字符(从 0 开始)。
val str = "Scala"
println(str(0)) // 输出: S
2. 常用方法
- 大小写转换:
val str = "Scala"
println(str.toUpperCase) // 输出: SCALA
println(str.toLowerCase) // 输出: scala
- 子字符串:
val str = "Hello, Scala"
println(str.substring(0, 5)) // 输出: Hello
- 查找和替换:
val str = "Hello, Scala"
println(str.contains("Scala")) // 输出: true
println(str.replace("Scala", "World")) // 输出: Hello, World
- 分割:
val str = "apple,banana,orange"
val fruits = str.split(",")
println(fruits.mkString(" | ")) // 输出: apple | banana | orange
- 去空格:
val str = " Scala "
println(str.trim) // 输出: Scala
3. 函数式操作
字符串可以看作字符序列(Seq[Char]
),支持 Scala 的集合操作:
val str = "Scala"
val chars = str.map(_.toUpper) // 输出: SCALA
val filtered = str.filter(_ != 'a') // 输出: Scl
println(chars, filtered)
4. 字符串插值
Scala 提供了字符串插值(String Interpolation),通过在字符串前加前缀(如 s
, f
, raw
)嵌入变量或表达式,简化格式化。
1. s
插值
- 用于嵌入变量或表达式,用
$
或${}
表示。 - 语法:
s"字符串内容 $变量 ${表达式}"
- 示例:
val name = "Scala"
val age = 15
println(s"Hello, $name! Age: $age") // 输出: Hello, Scala! Age: 15
println(s"Next year: ${age + 1}") // 输出: Next year: 16
2. f
插值
- 用于格式化字符串,支持类似 C 的
printf
风格。 - 语法:
f"字符串内容 $变量%格式"
- 示例:
val pi = 3.14159
println(f"Pi: $pi%.2f") // 输出: Pi: 3.14
println(f"Name: $name%10s") // 输出: Name: Scala
3. raw
插值
- 忽略转义字符,保留原始内容。
- 示例:
println(raw"Line\nBreak") // 输出: Line\nBreak
5. 多行字符串
Scala 支持用三重双引号 """
定义多行字符串,适合表示多行文本或忽略转义字符:
val multiLine = """Line 1
Line 2
Line 3"""
println(multiLine)
// 输出:
// Line 1
// Line 2
// Line 3
- 去掉前导空格:使用
stripMargin
方法去除每行开头的|
前的空格:
val formatted = """|Line 1
|Line 2
|Line 3""".stripMargin
println(formatted)
// 输出:
// Line 1
// Line 2
// Line 3
6. 转义字符
字符串支持转义字符(详见前文讲解),如 \n
(换行)、\t
(制表符)等:
val str = "Hello\nScala"
println(str)
// 输出:
// Hello
// Scala
- 注意:在
raw
插值或"""
字符串中,转义字符不生效。
7. 注意事项
- 不可变性:字符串操作(如
replace
)生成新字符串,原字符串不变。 - 性能:
- 频繁拼接推荐使用
StringBuilder
:scala val sb = new StringBuilder sb.append("Hello").append(", ").append("Scala") println(sb.toString) // 输出: Hello, Scala
- 小规模拼接可用
+
或插值。 - 与 Java 兼容:Scala 字符串直接调用 Java 的
String
方法。 - Scala 2 vs Scala 3:
- 字符串插值语法一致,但 Scala 3 优化了语法(更简洁)。
- Scala 3 增强了类型推断和错误提示。
- 避免 null:推荐使用
Option[String]
替代null
:
val opt: Option[String] = Some("Scala")
println(opt.getOrElse("Default")) // 输出: Scala
8. 实践示例
综合示例,展示字符串的各种操作:
object StringDemo {
def main(args: Array[String]): Unit = {
// 基本字符串
val str = "Hello, Scala"
println(s"Length: ${str.length}") // 输出: Length: 12
println(s"Upper: ${str.toUpperCase}") // 输出: Upper: HELLO, SCALA
// 字符串插值
val name = "Alice"
val age = 25
println(s"Name: $name, Age: $age") // 输出: Name: Alice, Age: 25
println(f"Age next year: ${age + 1}%d") // 输出: Age next year: 26
// 多行字符串
val multi = """|First line
|Second line
|Third line""".stripMargin
println(multi)
// 输出:
// First line
// Second line
// Third line
// 函数式操作
val chars = str.filter(_ != ',')
println(chars) // 输出: Hello Scala
// StringBuilder
val sb = new StringBuilder
sb.append("Scala").append(" is fun!")
println(sb.toString) // 输出: Scala is fun!
}
}
9. 学习建议
- 实践:在 Scala REPL(运行
scala
命令)中测试字符串操作和插值,观察输出。 - 函数式思维:结合
map
,filter
等方法处理字符串。 - 性能优化:学习
StringBuilder
用于高频字符串拼接。 - 资源:
- 官方文档:https://www.scala-lang.org/
- Scala Exercises (https://www.scala-exercises.org/)
- 《Programming in Scala》by Martin Odersky
如果需要深入讲解某一方面(如字符串插值或 StringBuilder
优化)或更多示例,请告诉我!