字符串与字符
理解 Swift 字符串的 Unicode 模型、内存管理机制,以及 Swift 6 时代的现代字符串处理技术(RegexBuilder)和并发安全性。
Swift 的 String 类型是现代编程语言中对文本处理最严谨、最强大的实现之一。它不仅完全兼容 Unicode 标准,还通过值语义和写时复制(CoW)保证了高性能与安全性。本文将从底层原理到 Swift 6 的最新特性,带你全面掌握 Swift 字符串。
字符串基础 (String Basics)
字面量
除了常规的双引号,Swift 还支持多行字符串和扩展分隔符。
// 多行字符串
let xml = """
<root>
<user>Alice</user>
</root>
"""
// 扩展分隔符(无需转义引号)
let json = #"{ "name": "Bob" }"#初始化
String 是结构体,初始化开销极低。
let empty = ""
let repeated = String(repeating: "A", count: 5) // "AAAAA"字符与 Unicode (Characters & Unicode)
Swift 的 String 是 Character 的集合。理解 Character 是理解 Swift 字符串的关键。
扩展字素簇 (Extended Grapheme Clusters)
Swift 的 Character 代表一个人类可读的“字符”,无论它由多少个 Unicode 标量组成。例如,é 可以是一个标量,也可以是 e 加上重音符组合而成,在 Swift 中它们被视为同一个字符。
let eAcute: Character = "\u{E9}" // é
let combinedEAcute: Character = "\u{65}\u{301}" // e + ́
// 两者相等,且 count 均为 1这种设计虽然增加了底层复杂度,但保证了文本处理的逻辑正确性。
字符串操作 (String Manipulation)
索引 (Indices)
由于字符长度不固定,Swift 不支持整数索引(str[0]),而是使用 String.Index。
let greeting = "Hello"
let start = greeting.startIndex
let end = greeting.index(before: greeting.endIndex)
let char = greeting[start] // "H"插入与删除
var welcome = "hello"
welcome.insert("!", at: welcome.endIndex)
welcome.remove(at: welcome.index(before: welcome.endIndex))子字符串 (Substrings)
当你对字符串进行切片时,得到的是 Substring 类型。
let full = "Hello, World"
let index = full.firstIndex(of: ",") ?? full.endIndex
let sub = full[..<index] // "Hello" (类型为 Substring)内存共享:Substring 重用原 String 的内存,极其高效。但这也意味着如果长期持有子串,原字符串的内存无法释放。因此,若需长期存储,应将其转换为 String。
let newString = String(sub) // 复制内存,释放原字符串引用现代字符串处理 (Regex & Swift 6)
Swift 5.7 引入了原生的正则表达式支持,并在后续版本中不断完善。
RegexBuilder
使用声明式语法构建正则表达式,可读性极高。
import RegexBuilder
let search = Regex {
OneOrMore(.digit)
"@"
OneOrMore(.word)
}
let input = "Contact: 123@example"
if let match = input.firstMatch(of: search) {
print(match.0) // "123@example"
}Regex 字面量
let regex = /[a-z0-9]+@[a-z]+\.[a-z]{2,}/性能与并发 (Performance & Concurrency)
UTF-8 视图
Swift 字符串底层默认使用 UTF-8 编码。通过 utf8 视图访问字节数据非常高效,常用于网络传输或底层解析。
let data = "Hello".utf8 // 无需拷贝Sendable 与并发
String 是值类型,天然遵循 Sendable 协议。在 Swift 6 的严格并发检查下,你可以放心地在 Actor 之间传递字符串,无需担心数据竞争。
actor Logger {
func log(_ message: String) {
print(message)
}
}
// String 传递是安全的(发生拷贝)总结
Swift 的字符串设计在正确性(Unicode)和性能(CoW、UTF-8)之间取得了极佳的平衡。结合现代的 RegexBuilder 和 Swift 6 的并发特性,处理文本变得既优雅又高效。
上次更新于