以下所有示例都使用
var str = "Hello, playground"
startIndex
and endIndex
startIndex
是第一个字符的索引
endIndex
是最后一个字符的索引after.
实例
// character
str[str.startIndex] // H
str[str.endIndex] // error: after last character
// range
let range = str.startIndex..<str.endIndex
str[range] // "Hello, playground"
使用Swift 4的one-sided ranges,范围可以简化为以下形式之一.
let range = str.startIndex...
let range = ..<str.endIndex
为了清晰起见,我将在下面的示例中使用完整的形式,但为了可读性,您可能希望在代码中使用单边范围.
after
例如:index(after: String.Index)
实例s
// character
let index = str.index(after: str.startIndex)
str[index] // "e"
// range
let range = str.index(after: str.startIndex)..<str.endIndex
str[range] // "ello, playground"
before
例如:index(before: String.Index)
实例s
// character
let index = str.index(before: str.endIndex)
str[index] // d
// range
let range = str.startIndex..<str.index(before: str.endIndex)
str[range] // Hello, playgroun
offsetBy
例如:index(String.Index, offsetBy: String.IndexDistance)
offsetBy
的值可以是正的,也可以是负的,并且从给定的索引开始.虽然它是String.IndexDistance
型的,但你可以给它打Int
.
实例s
// character
let index = str.index(str.startIndex, offsetBy: 7)
str[index] // p
// range
let start = str.index(str.startIndex, offsetBy: 7)
let end = str.index(str.endIndex, offsetBy: -6)
let range = start..<end
str[range] // play
limitedBy
例如:index(String.Index, offsetBy: String.IndexDistance, limitedBy: String.Index)
limitedBy
有助于确保偏移量不会导致索引超出范围.它是一个边界索引.由于偏移量有可能超过限制,因此此方法返回可选值.如果索引超出范围,则返回nil
.
实例
// character
if let index = str.index(str.startIndex, offsetBy: 7, limitedBy: str.endIndex) {
str[index] // p
}
如果偏移量是77
而不是7
,那么if
语句将被跳过.
Why is String.Index needed?
对字符串使用Int
索引会更容易.您必须 for each 字符串创建一个新的String.Index
的原因是Swift中的字符在引擎盖下的长度不尽相同.单个Swift字符可能由一个、两个或更多Unicode代码点组成.因此,每个唯一字符串必须计算其字符的索引.
可以在Int索引扩展后面隐藏这种复杂性,但我不愿意这样做.提醒自己实际发生的事情是件好事.