在 Swift 中,String
是一种用于操作和表示文本的强大数据类型。它是 Unicode 兼容的,可存储和操作多种语言文字,并且提供了丰富的接口(方法和属性)来进行字符串操作。以下是 Swift String
的常用接口和功能分类介绍。
1. String 的基本属性与信息 #
属性或方法 | 功能说明 | 示例 |
---|---|---|
isEmpty | 判断字符串是否为空,返回 true 或 false 。 | let isEmpty = str.isEmpty |
count | 返回字符串中字符的数量(按字符计算,而非字节)。 | let length = str.count |
first | 返回字符串的第一个字符(可选类型,空字符串返回 nil )。 | let firstChar = str.first |
last | 返回字符串的最后一个字符(可选类型,空字符串返回 nil )。 | let lastChar = str.last |
lowercased() | 返回字符串的小写版本。 | let lower = str.lowercased() |
uppercased() | 返回字符串的大写版本。 | let upper = str.uppercased() |
capitalized | 返回首字母大写、其余小写的字符串版本。 | let capitalized = str.capitalized |
2. 创建 String #
方式 | 功能说明 | 示例 |
---|---|---|
字面量方式 | 使用双引号直接创建字符串。 | let str = "Hello World" |
空字符串 | 使用 "" 或 String() 创建空字符串。 | let empty = "" |
多行字符串 | 使用三对双引号创建多行字符串。 | `let multiline = """ |
Line1 | ||
Line2 | ||
“”"` |
3. 访问 #
方法或特性 | 功能说明 | 示例 |
---|---|---|
subscript(_:) | 使用下标访问或获取字符串中指定位置的字符(按索引)。 | let char = str[str.index(str.startIndex, offsetBy: 5)] |
startIndex | 获取字符串的起始索引。 | let start = str.startIndex |
endIndex | 获取字符串的结束索引,表示最后一个字符的后一个位置。 | let end = str.endIndex |
indices | 获取字符串中所有字符的索引集合。 | for index in str.indices { print(str[index]) } |
4. 搜索和判断 #
方法 | 功能说明 | 示例 |
---|---|---|
contains(_:) | 判断字符串是否包含指定字符或子字符串。 | let isFound = str.contains("Hello") |
starts(with:) | 检查字符串是否以指定子字符串开头,返回 true 或 false 。 | let starts = str.starts(with: "Hello") |
ends(with:) | 检查字符串是否以指定子字符串结尾,返回 true 或 false 。 | let ends = str.hasSuffix("World") |
firstIndex(of:) | 返回指定字符的第一个匹配的索引位置(可选类型,当不存在时为 nil )。 | let index = str.firstIndex(of: "o") |
lastIndex(of:) | 返回字符的最后一个匹配的索引位置(可选类型)。 | let index = str.lastIndex(of: "o") |
5. 修改 #
方法 | 功能说明 | 示例 |
---|---|---|
append(_:) | 向字符串末尾追加字符或另一个字符串。 | str.append("Swift") |
insert(_:at:) | 在指定索引位置插入字符或字符串。 | str.insert("!", at: str.endIndex) |
remove(at:) | 移除指定索引位置的字符,并返回被删除的字符。 | let removedChar = str.remove(at: str.startIndex) |
removeAll() | 移除字符串中的所有字符,变成一个空字符串。 | str.removeAll() |
replaceSubrange(_:with:) | 替换指定索引范围内的字符串内容。 | str.replaceSubrange(str.startIndex..<str.index(str.startIndex, offsetBy: 5), with: "Hello!") |
6. 遍历 #
方法 | 功能说明 | 示例 |
---|---|---|
for-in | 遍历字符串中的每个字符。 | for char in str { print(char) } |
forEach(_:) | 使用闭包依次遍历每个字符。 | str.forEach { print($0) } |
7. 拼接与组合 #
方法 | 功能说明 | 示例 |
---|---|---|
+ | 使用加号拼接多个字符串,生成一个新字符串。 | let result = "Hello" + " World" |
+ = | 将右侧字符串拼接到左侧字符串中,直接修改左侧字符串。 | str += "!" |
joined(separator:) | 用指定的分隔符将字符串数组拼接成一个字符串。 | let result = ["A", "B", "C"].joined(separator: "-") |
8. 截取 (Substrings) #
方法 | 功能说明 | 示例 |
---|---|---|
prefix(_:) | 返回字符串中从开头到指定长度的部分字符串。 | let prefix = str.prefix(5) |
suffix(_:) | 返回字符串中从结尾开始指定长度的部分字符串。 | let suffix = str.suffix(3) |
dropFirst(_:) | 去掉字符串的前 N 个字符,返回剩余部分。 | let result = str.dropFirst(2) |
dropLast(_:) | 去掉字符串的最后 N 个字符,返回剩余部分。 | let result = str.dropLast(1) |
substring(with:) | 根据索引范围截取字符串的一部分。 | let sub = str[str.startIndex..<str.endIndex] |
9. 替换 #
方法 | 功能说明 | 示例 |
---|---|---|
replacingOccurrences(of:with:) | 替换字符串中指定的所有子字符串为新的内容。 | let newStr = str.replacingOccurrences(of: "World", with: "Swift") |
replacingCharacters(in:with:) | 替换字符串中指定索引范围内的字符为新的内容。 | str = str.replacingCharacters(in: str.startIndex..<str.index(str.startIndex, offsetBy: 5), with: "Hi") |
10. 字符串与其他类型的转换 #
方法 | 功能说明 | 示例 |
---|---|---|
Int(_:) | 将字符串转换为整型,如果不能转换则为 nil 。 | let num = Int("123") // 123 |
Double(_:) | 将字符串转换为浮点数,如果不能转换则为 nil 。 | let value = Double("3.14") // 3.14 |
description | 获取字符串的文本描述。 | let desc = str.description |
11. 大小写变换 #
方法 | 功能说明 | 示例 |
---|---|---|
lowercased() | 转为小写形式。 | let lower = str.lowercased() |
uppercased() | 转为大写形式。 | let upper = str.uppercased() |
capitalized | 转为每个单词首字母大写的形式。 | let title = str.capitalized |
12. 注意事项 (Unicode 和字符处理) #
字符串是 Unicode-aware 的:
Swift 的字符串完全支持 Unicode 标准,对于包含多种语言的文本可以安全地存储和操作。字符和索引:
- Swift 的字符串使用 索引 (
String.Index
) 代替简单整数来访问字符,这是因为字符串的字符可以是多个字节宽度的。 - 你必须通过
startIndex
和endIndex
配合index
方法获取指定位置的字符。
- Swift 的字符串使用 索引 (
不可变性:
Swift 中的字符串是值类型,每次修改字符串都会生成新的值。
示例代码 #
1. 遍历字符串并截取 #
let str = "Hello, Swift"
for char in str {
print(char) // 输出:依次打印每个字符
}
// 截取前 5 个字符
let prefix = str.prefix(5) // "Hello"
2. 字符串替换 #
var str = "Hello, World"
str = str.replacingOccurrences(of: "World", with: "Swift") // "Hello, Swift"
3. 检查字符串是否包含内容 #
let str = "Learn Swift"
if str.contains("Swift") {
print("String contains 'Swift'")
}
if str.starts(with: "Learn") {
print("Starts with 'Learn'")
}
4. 拼接多个字符串 #
let part1 = "I love"
let part2 = " Swift"
let sentence = part1 + part2 // "I love Swift"
5. 获取字符串长度 #
let str = "Hello"
let length = str.count // 输出:5
总结 #
常用功能: #
- 创建与访问: 字符串可以通过索引访问字符,支持
startIndex
和endIndex
。 - 修改: 支持插入、删除、替换、追加等操作。
- 查找:
contains
、firstIndex(of:)
、starts(with:)
。 - 拼接:
+
、append
、joined
。 - 转换: 支持与
Int
、Double
等类型的转换。
适用场景: #
Swift 的 String
适用于所有文本操作需求。如果需要处理字符串或解析文本,String
提供了丰富强大的工具和功能。
字符串插值 #
本地化字符串插值是一种在动态生成本地化字符串时嵌入变量或格式化参数的技术,其核心目标是将动态数据(如用户名称、日期、数字等)与本地化文本无缝结合,同时遵循不同语言区域的格式规范。从体系结构的角度,这一机制在 Swift/SwiftUI 中通过多层抽象实现,以下是其根本原理:
一、基础架构:字符串插值与类型系统 #
字符串插值的本质
字符串插值在 Swift 中通过ExpressibleByStringInterpolation
协议实现,允许在编译时将\(变量)
表达式转换为特定类型的中间表示。例如,普通字符串插值直接拼接内容,而本地化插值则生成LocalizedStringKey
结构体。
示例:Text("date: \(date(), style: .date)")
会被解析为LocalizedStringKey
的实例,携带日期对象及样式参数。类型安全与本地化键
SwiftUI 的Text
视图默认使用LocalizedStringKey
初始化,该类型实现了ExpressibleByStringInterpolation
,从而支持在插值时嵌入非字符串类型(如Image
、Date
)并保留类型信息。这种设计保证了编译时类型检查,避免运行时格式错误。
二、运行时处理:本地化资源与参数替换 #
本地化资源加载
当LocalizedStringKey
被创建时,系统会根据当前语言环境从Localizable.strings
或Localizable.stringsdict
文件中查找匹配的键值对。例如,键"welcome_message"
对应不同语言的翻译文本。动态参数替换机制
插值中的变量(如userName
)会被映射到本地化字符串中的占位符(如%@
)。例如:Localize("personalized_greeting", userName) // 对应字符串定义:"你好, %@!"
运行时,占位符会根据参数类型(字符串、数字等)自动适配本地化格式(如千位分隔符、日期格式)。
三、体系结构中的关键组件 #
编译器角色
- 插值解析:将
\(变量)
转换为LocalizedStringKey.Interpolation
的片段。 - 类型推断:检查插值变量是否支持
FormatSpecifiable
协议(如Date
需指定.date
样式)。
- 插值解析:将
运行时组件
- 本地化资源管理器:从 Bundle 加载对应语言的字符串文件。
- 格式化器(Formatters):处理数字、日期等类型的本地化转换(如
NumberFormatter
或DateFormatter
)。
扩展性设计
- 自定义类型支持:通过实现
_FormatSpecifiable
协议,允许开发者将自定义类型(如Person
)嵌入本地化字符串。 - 动态资源更新:部分框架(如 Localize-Swift)支持运行时动态加载新的翻译资源。
- 自定义类型支持:通过实现
四、与普通字符串插值的区别 #
特性 | 普通插值 | 本地化插值 |
---|---|---|
目标 | 直接拼接字符串 | 动态生成符合区域格式的本地化文本 |
类型处理 | 转换为 String | 保留原始类型(如 Date 、Image ) |
资源依赖 | 无 | 依赖 Localizable.strings 文件 |
运行时开销 | 低 | 需查询本地化资源并格式化参数 |
五、典型应用场景 #
动态数据展示
如用户个人主页显示“欢迎回来,{用户名}”,其中用户名需适配不同语言的语序。复杂格式本地化
使用stringsdict
文件处理复数形式(如英文的 “1 item” vs. “5 items”)。图文混排
在文本中嵌入图标(如Text("点击 \(Image(systemName: "arrow.right")) 继续")
)。
通过以上架构设计,本地化字符串插值实现了类型安全、动态适配和高效资源管理的平衡,成为构建国际化应用的核心技术之一。具体实现细节可参考 Swift 的 LocalizedStringKey
源码及 ExpressibleByStringInterpolation
协议文档。