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

