前言
Swift 的 String 看起来"像 NSString 的弟弟",但骨子里是一套全新的 Unicode 抽象模型。
String 与 Character 的本质
- String:由"扩展字形簇"(extended grapheme cluster)构成的有序集合。
- Character:一个扩展字形簇,人类眼中的"一个字符",占用的字节数可变。
swift
// 1 个 Character,由 2 个 Unicode 标量合成
let eAcute: Character = "é" // "é"
let eCombining: Character = "\u{65}\u{301}" // "e" + "́" 组合
print(eAcute == eCombining) // true,两者字形簇等价
字符串字面量:单行、多行、转义、扩展分隔符
单行字面量
swift
let msg = "Hello, Swift" // 类型自动推断为 String
多行字面量
swift
let html = """
<div>
<p>Hello</p>
</div>
""" // 缩进 4 空格会被自动去掉,因为闭合 """ 在最左侧第 12 列
// 闭合"""左侧的空格会被删除,每一行左侧的同等长度的空格都会被删除
换行控制技巧
swift
let sql = """
SELECT * FROM user \
WHERE age > 18
""" // 反斜杠让源码换行,但字符串里无换行
转义序列
swift
let special = "双引号:\",制表:\t,换行:\n,Unicode:\u{1F496}"
扩展分隔符(#)
场景:正则、JSON 模板里想保留原始反斜杠。
swift
let raw = #"Raw \n still two characters"#
let needEscape = #"Use \#n to enable line break"#
print(raw) // 输出:Raw \n still two characters
print(needEscape)// 输出:Use
// to enable line break
多行 + 扩展分隔符
swift
let mlRaw = #"""
Line 1
Line 2
"""#
空字符串的 3 种创建方式
swift
let a = ""
let b = String()
let c = String("") // 与前两种等价
print(a.isEmpty) // true
可变性:let 与 var 的抉择
swift
let immutable = "can't change"
// immutable += "!" // ❌ Compile-time error
var mutable = "hello"
mutable += ", world" // ✅
值类型:写时复制(COW)到底发生了什么
swift
func foo(_ s: String) {
var local = s // 此时未复制,共享同一块缓冲区
local += "!" // 突变触发复制,O(n) 成本
print(local)
}
底层优化:仅当本地突变或跨线程时才真正拷贝,因此作为入参传递时无需担心性能。
字符集合:遍历、提取、构造
swift
let word = "Swift"
for ch in word {
print(ch, terminator: "-") // S-w-i-f-t-
}
let single: Character = "A"
let fromChars = String([single, "B", "C"]) // "ABC"
字符串拼接的 5 种姿势
swift
let left = "Hello"
let right = "World"
// 1. 加法
let s1 = left + ", " + right
// 2. 加法赋值
var s2 = left
s2 += ", " + right
// 3. append(Character)
var s3 = left
s3.append(",")
s3.append(" ")
s3.append(Character(right)) // 仅当 right 长度=1 时安全
// 4. append(contentsOf: String)
var s4 = left
s4.append(contentsOf: ", \(right)")
// 5. 多行拼接注意最后一行换行
let goodStart = """
Line 1
Line 2
"""
let end = """
Line 3
"""
let merged = goodStart + end // 3 行,无意外合并
字符串插值:最灵活的"模板引擎"
swift
let name = "Swift"
let year = 2025
let msg = "Hello, \(name)! In \(year + 1) we will rock."
print(msg) // Hello, Swift! In 2026 we will rock.
// 在扩展分隔符中使用插值
let rawLog = #"Level \#(name) recorded at \#(Date())"#
扩展场景:今天就能用上的 3 个小工具
彩色命令行日志
swift
func log(_ info: String) {
print(#"\u{1B}[32m[INFO]\#(info)\u{1B}[0m"#)
}
log("Server started") // 终端绿色输出
快速 Mock JSON
swift
let userId = 9527
let json = #"""
{"id": \#(userId), "name": "Alice"}
"""#
print(json) // 直接贴进 Postman 即可
多行 SQL 模板
swift
let table = "user"
let sql = """
SELECT *
FROM \(table)
WHERE status = 'active'
AND created_at > ?
"""