字符串与字符
本教程共 93 篇 · 第 10 篇 · 更新于 2026-08-08 · 约 8 分钟阅读
本节目标:读完你能分清 String 和 Character,知道字符串可变性的写法、如何遍历字符、以及如何判断字符串为空。
文本是程序里最常见的数据之一。Swift 用 String 表示一串文字,用 Character 表示单个字符。这一章先把这两个类型的关系和日常用法讲清楚,字符串的进阶操作留到后面两章。
1-1 字符串是什么
字符串就是一连串字符,比如 "hello, world" 或 "你好"。在 Swift 里,它对应的类型是 String。
let someString = "一些文字"
因为初值是字符串字面量,编译器推断 someString 是 String。字符串字面量就是包在双引号里的一串字符。
Swift 的字符串语法轻量好读:拼接用 +,可变性靠 let/var 决定,插值是 \()。它底层是快速且完全兼容 Unicode 的实现,但表面用起来却很简单。
1-2 字符 Character 是什么
Character 表示单个字符。你可以从一个单字符的字符串字面量,通过类型标注造出一个 Character:
let exclamationMark: Character = "!"
注意这里必须写 : Character,否则 "!" 会被推断成 String。单个字符在 Swift 里也是值类型,和字符串同源。
也可以用一个 Character 数组去构造字符串:
let catCharacters: [Character] = ["C", "a", "t", "!"]
let catString = String(catCharacters) // "Cat!"
1-3 字符串的可变性
字符串能不能改,由你用 let 还是 var 决定——和 Swift 里其他值一样,没有专门的”可变字符串类”。
var variableString = "马"
variableString += "和车"
// 现在是 "马和车"
let constantString = "高地人"
constantString += "和另一个高地人"
// 编译错误:常量字符串不能改
这套方式和 Objective-C 不同(那边要用 NSString 和 NSMutableString 两个类区分)。Swift 统一用 let/var 表达,更一致,也更符合”值本身很少需要变就别让它变”的安全思路。
1-4 字符串是值类型
这是一个关键认知:String 是值类型。当你把字符串赋给另一个变量、或传给函数时,Swift 会拷贝一份新副本,而不是共享同一块内存。
var original = "原始"
var copy = original
copy += "副本"
// original 仍是 "原始",copy 是 "原始副本"
好处很明确:你拿到的字符串,除非你自己改,否则绝不会被别处的代码偷偷改动。这让你在函数之间传递文本时心里有底。
底层编译器很聪明,只在真正需要时才会发生拷贝,所以你享受值类型的安全,却不必担心性能损耗。
1-5 遍历字符串里的字符
想一个一个看字符串里的字符,用 for-in 循环最直观:
for character in "狗!🐶" {
print(character)
}
// 依次打印:狗、!、🐶
这里每个 character 都是 Character 类型,包含的可能是一个字母、一个汉字,也可能是一个 emoji。注意 emoji 也算一个字符——这背后和 Unicode 有关,下一章字符串进阶会细讲,这里先知道”一个字一个字符”的直觉在 Swift 里大致成立。
1-6 判空 isEmpty
判断字符串有没有内容,用 isEmpty 属性,比判断 count == 0 更地道:
var emptyString = ""
if emptyString.isEmpty {
print("这里啥也没有")
}
isEmpty 返回布尔值,写条件判断特别顺手。
1-7 创建空字符串的两种方式
想从空字符串开始,逐步拼内容,有两种写法,效果等价:
var empty1 = "" // 空字符串字面量
var empty2 = String() // 初始化语法
两者都是空 String,可以随意往里追加内容。选哪种都行,字面量 "" 更短更常见。
1-8 字符串比较
两个字符串相等与否,用 == 和 != 判断,和整数比较一个样:
let q1 = "我们很像"
let q2 = "我们很像"
if q1 == q2 {
print("这两个字符串相等")
}
Swift 的字符串相等是基于”规范等价”的:即使两个字符串背后由不同的 Unicode 标量组合而成,只要表达的意思和样子一样,就判为相等。这点后面讲 Unicode 时会展开。现阶段记住:比字符串用 ==,别自己写长度比较。
Note字符串还能判断是否以某前缀/后缀开头或结尾(
hasPrefix、hasSuffix),以及用count数字符个数。这些方法都很常用,但涉及 Unicode 计数的坑,我们放到”字符串进阶”那一章专门说。
1-9 字符串的几个脾气
字符串是日常打交道最多的类型,把它的几个脾气吃透,能省很多后续麻烦。String 是值类型这件事影响深远:赋值和传参会拷贝(底层按需优化),所以你拿到的字符串除非自己改,不会被别处偷偷变动。这种”默认安全”在多人协作、函数传参时特别安心。
可变性由 let/var 决定,没有专门的”可变字符串类”,这和 Objective-C 的 NSString/NSMutableString 两件套不同。统一用 let/var 表达,更一致,也更符合 Swift”值不变就别让它变”的思路。
遍历字符用 for-in,每个 character 是一个 Character,包含字母、汉字甚至 emoji。这里先建立”一个字一个字符”的直觉,但要知道 emoji 也算一个字符——这和 Unicode 有关,下一章进阶会揭示背后的坑。
判空用 isEmpty 而非 count == 0,比较用 == 而非自己比长度。这两个习惯看似小,却能让代码更地道、更少出错。字符串还能判断前缀后缀(hasPrefix/hasSuffix)、数字符个数(count),这些方法很常用,记住它们存在即可,细节留到进阶章展开。
字符串拼接用 + 或 += 没问题,但大量拼接时反复生成新字符串略有开销。日常小文本无所谓;真要拼很多段,后面会学到用更高效的方式。初学阶段,+ 和插值够用了。把字符串当”值类型 + 不可变优先”来理解,很多行为就顺了。看到常量字符串不能改、赋值会拷贝,不要惊讶,那是 Swift 在保护你。基础打牢,下一章讲拼接插值时你会更从容。
1-10 补记:字符数与字节数
还有个容易忽略的点:字符串的 count 和”占多少字节”是两回事。一个英文字母占 1 字节,一个汉字通常占 3 字节(UTF-8 下),一个 emoji 可能占 4 字节甚至更多。所以”字符数”和”字节长度”往往不一致。做网络传输、数据库存储时要按字节算大小,做界面显示时按字符数算——别把两者混为一谈,否则中文内容特别容易算错长度。
1-11 小结
String 是一串文本,Character 是单个字符;声明单字符要写 : Character。字符串可变性由 let/var 决定,没有专门的可变类。它是值类型,赋值和传参会拷贝(底层按需优化),所以默认安全。遍历用 for-in,判空用 isEmpty,比较用 ==。下一章讲字符串的拼接、插值和多行写法,以及类型转换与别名。