初始化空串
- 字面量
- 初始化器语法
- isEmpty 检查是否为空串
// 字面量
var emptyString = ""
// 初始化器
var anotherEmptyString = String()
// isEmpty 检查是否为空串
if emptyString.isEmpty {
print("空字符串")
}
字符串字面量是被双引号(”)包裹的固定顺序文本字符
Swift 会为 str 常量推断类型为 String
多行字面量
- 多行字符串字面量是用三个双引号引起来的一系列字符
- 多行字符串字面量把所有行包括在引号内,开始和结束默认不会有换行符
-
当你的代码中在多行字符串字面量里包含了换行,那个换行符同样会成为字符串里的值。如果你想要使 用换行符来让你的代码易读,却不想让换行符成为字符串的值,那就在那些行的末尾使用反斜杠( \ )
多行字面量
末尾使用反斜杠( \ )
- 要让多行字符串字面量起始或结束于换行,就在第一或最后一行写一个空行
- 多行字符串可以缩进以匹配周围的代码。双引号( """ )前的空格会告诉 Swift 其他行前应 该有多少空白是需要忽略的
-
如果你在某行的空格超过了结束的双引号( """ ),那么这些空格会被包含
字符串里的特殊字符
- 转义特殊字符 \0 (空字符), \ (反斜杠), \t (水平制表符), \n (换行符), \r(回车符), " (双引号) 以及 ' (单引号)
- 任意的 Unicode 标量,写作 \u{n},里边的 n 是一个 1-8 位的16 进制数字,其值是合法 Unicode 值
- 可以在多行字符串字面量中包含双引号( " )而不需转义。要在多行字符串中包含文本 """ ,转义至 少一个双引号
let wiseWords = "这是正在热播的电视剧《我们的日子》中的剧情,男主演就是我们很熟悉的男演员\"李乃文\"。"
print(wiseWords) // 打印结果: 这是正在热播的电视剧《我们的日子》中的剧情,男主演就是我们很熟悉的男演员"李乃文"。
let dollarSign = "\u{24}"
print(dollarSign) // 打印结果: $
let blackHeart = "\u{2665}"
print(blackHeart) // 打印结果: ♥
let redHeart = "\u{1F496}"
print(redHeart) // 打印结果: 💖
扩展字符串分隔符(Raw String)
- 在字符串字面量中放置扩展分隔符来在字符串中包含特殊字符而不让它们真的生效
- 把字符串放在双引号( " )内并由井号( # )包裹
- 如果字符串里有 "# 则首尾需要两个 ##
- 如果你需要字符串中某个特殊符号的效果,使用匹配你包裹的井号数量的井号并在前面写转义符号 \
let str = #"Line 1 \n Line 2"# // 两个#号中的所有转义符失效
print(str)
let str1 = #"Line 3 \#nLine 4 \\ "# // 转义符中间加有一个#,表示该转义符可以生效,没有加#的其他转义符无效
print(str1)
let str2 = ###"Line 5 \###nLine 6 \###\ "###
print(str2)
字符串的可变性
- var 指定的可以修改
- let 指定的不可修改
- 对比 Objective-C(NSString 和 NSMutableString)
var name = "姓名:"
name += "张三"
print(name) // 打印结果: 姓名:张三
let name = "姓名:"
name += "张三"
print(name) // error: Left side of mutating operator isn't mutable: 'name' is a 'let' constant
字符串是值类型
- String 值在传递给方法或者函数的时候会被复制过去
- 赋值给常量或者变量的时候也是一样
- Swift 编译器优化了字符串使用的资源,实际上拷贝只会在确实需要的时候才进行
var name: String = "张三"
var nickname = name
print(name == nickname) // 打印结果: true
name += " 昵称"
print("name: \(name)") // 打印结果: 张三 昵称
print("nickname: \(nickname)") // 打印结果: 张三
print(name == nickname) // 打印结果: false
操作字符
- for-in 循环遍历 String 中的每一个独立的 Character
- Character 类型
- String 值可以通过传入 Character 数组来构造
for char in "Dog!🐶" {
print(char)
}
let cat: [Character] = ["C", "a", "t", "!", "🐱"]
let catString = String(cat)
print(catString)
字符串拼接
- 使用加运算符( +)创建新字符串
- 使用加赋值符号( +=)在已经存在的 String 值末尾追加一个 String 值
- 使用 String 类型的 append() 方法来可以给一个 String 变量的末尾追加 Character 值
var name: String = "我的姓名是"
name += ":张三"
print(name) // 打印结果: 我的姓名是:张三
字符串插值
- 字符串插值是一种从混合常量、变量、字面量和表达式的字符串字面量构造新 String 值的方法
- 每一个你插入到字符串字面量的元素都要被一对圆括号包裹,然后使用反斜杠前缀
- 类似于 NSString 的 stringWithFormat 方法,但是更加简便,更强大
var name: String = "我的姓名是"
name += ":张三"
var age = "20"
print("\(name), 年龄:\(age)") // 打印结果: 我的姓名是:张三, 年龄:20
let multiplier = 3
let message = "\(multiplier) times 2.5 is \(Double(multiplier) * 2.5)"
print(message) // 打印结果: 3 times 2.5 is 7.5
字符串插值
- 可以在扩展字符串分隔符中创建一个包含在其他情况下会被当作字符串插值的字符
- 要在使用扩展分隔符的字符串中使用字符串插值,在反斜杠后使用匹配首尾井号数量的井号
print(#"Write an interpolated string in Swift using \(multiplier)."#) // Write an interpolated string in Swift using \(multiplier).
print(#"6 times 7 is \#(6*7)."#) // 6 times 7 is 42.
字符串索引
- 每一个 String 值都有相关的索引类型, String.Index,它相当于每个 Character 在字符串中的位置
- startIndex 属性来访问 String 中第一个 Character 的位置。 endIndex 属性就是 String中最后一个 字符后的位置
- endIndex 属性并不是字符串下标脚本的合法实际参数
- 如果 String 为空,则 startIndex 与 endIndex 相等
let content = "每一个 String 值都有相关的索引类型"
let chat = content[content.startIndex]
print(chat) // 每
- 使用 index(before:) 和 index(after:) 方法来访问给定索引的前后
- 要访问给定索引更远的索引,你可以使用 index(_:offsetBy:)
-
使用 indices 属性来访问字符串中每个字符的索引
插入
- 插入字符,使用 insert(_:at:) 方法
- 插入另一个字符串的内容到特定的索引,使用 insert(contentsOf:at:) 方法
删除
- 移除字符,使用 remove(at:)方法
- 移除一小段特定范围的字符串,使用 removeSubrange(_:) 方法
var content = "Hello"
content.insert("!", at: content.endIndex)
content.insert(contentsOf: " there", at: content.index(before: content.endIndex))
content.remove(at: content.startIndex)
print(content) // ello there!
let range = content.index(content.endIndex, offsetBy: -6)..<content.endIndex
content.removeSubrange(range)
print(content) // ello
子字符串
-
使用下标或者类似 prefix(_:) 的方法得到的子字符串是 Substring 类型
-
Substring 拥有 String 的大部分方法
-
Substring 可以转成 String 类型
-
子字符串重用一部分原字符串的内存
-
修改字符串或者子字符串之前都不需要花费拷贝内存的代价
-
String 和 Substring 都遵循 StringProtocol 协议,也就是说它基本上能很方便地兼容所有 接受 StringProtocol 值的字符串操作函数
字符串比较
- 字符串和字符相等性(==和!=)
- 前缀相等性 hasPrefix(_:)
- 后缀相等性 hasSuffix(_:)
网友评论