4.11. 访问和修改字符串

你可以通过字符串的属性和方法来访问和修改它,当然也可以用下标语法完成。

字符串索引

每一个 String 值都有一个关联的索引(index)类型,String.Index,它对应着字符串中的每一个 Character 的位置。

前面提到,不同的字符可能会占用不同数量的内存空间,所以要知道 Character 的确定位置,就必须从 String 开头遍历每一个 Unicode 标量直到结尾。因此,Swift 的字符串不能用整数(integer)做索引。

使用 startIndex 属性可以获取一个 String 的第一个 Character 的索引。使用 endIndex 属性可以获取最后一个 Character 的后一个位置的索引。因此,endIndex 属性不能作为一个字符串的有效下标。如果 String 是空串,startIndexendIndex 是相等的。

通过调用 Stringindex(before:)index(after:) 方法,可以立即得到前面或后面的一个索引。你还可以通过调用 index(_:offsetBy:) 方法来获取对应偏移量的索引,这种方式可以避免多次调用 index(before:)index(after:) 方法。

你可以使用下标语法来访问 String 特定索引的 Character

let greeting = "Guten Tag!"
greeting[greeting.startIndex]
// G
greeting[greeting.index(before: greeting.endIndex)]
// !
greeting[greeting.index(after: greeting.startIndex)]
// u
let index = greeting.index(greeting.startIndex, offsetBy: 7)
greeting[index]
// a

试图获取越界索引对应的 Character,将引发一个运行时错误。

greeting[greeting.endIndex] // error
greeting.index(after: greeting.endIndex) // error

使用 indices 属性会创建一个包含全部索引的范围(Range),用来在一个字符串中访问单个字符。

for index in greeting.indices {
   print("\(greeting[index]) ", terminator: "")
}
// 打印输出“G u t e n   T a g ! ”

注意:你可以使用 startIndexendIndex 属性或者 index(before:)index(after:)index(_:offsetBy:) 方法在任意一个确认的并遵循 Collection 协议的类型里面,如上文所示是使用在 String 中,你也可以使用在 ArrayDictionarySet 中。

插入和删除

调用 insert(_:at:) 方法可以在一个字符串的指定索引插入一个字符,调用 insert(contentsOf:at:) 方法可以在一个字符串的指定索引插入一个段字符串。

var welcome = "hello"
welcome.insert("!", at: welcome.endIndex)
// welcome 变量现在等于 "hello!"
welcome.insert(contentsOf:" there", at: welcome.index(before: welcome.endIndex))
// welcome 变量现在等于 "hello there!"

调用 remove(at:) 方法可以在一个字符串的指定索引删除一个字符,调用 removeSubrange(_:) 方法可以在一个字符串的指定索引删除一个子字符串。

welcome.remove(at: welcome.index(before: welcome.endIndex))
// welcome 现在等于 "hello there"
let range = welcome.index(welcome.endIndex, offsetBy: -6)..<welcome.endIndex
welcome.removeSubrange(range)
// welcome 现在等于 "hello"

注意:你可以使用 insert(_:at:)insert(contentsOf:at:)remove(at:)removeSubrange(_:) 方法在任意一个确认的并遵循 RangeReplaceableCollection 协议的类型里面,如上文所示是使用在 String 中,你也可以使用在 ArrayDictionarySet 中。