
Во всех следующих примерах используется
var str = "Hello, playground"
startIndex и endIndex
startIndex это индекс первого символа
endIndexэто индекс после последнего символа.
пример
// 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 диапазон можно упростить до одной из следующих форм.
let range = str.startIndex...
let range = ..<str.endIndex
Я буду использовать полную форму в следующих примерах для ясности, но для удобства чтения вы, вероятно, захотите использовать односторонние диапазоны в своем коде.
after
Как в: index(after: String.Index)
after относится к индексу символа сразу после данного индекса.
Примеры
// 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)
before относится к индексу символа непосредственно перед данным индексом.
Примеры
// 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.
Примеры
// 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полезно для того, чтобы убедиться, что смещение не приводит к выходу индекса за пределы. Это ограничивающий индекс. Поскольку смещение может превышать предел, этот метод возвращает значение Optional. Он возвращается, nilесли индекс выходит за пределы.
пример
// character
if let index = str.index(str.startIndex, offsetBy: 7, limitedBy: str.endIndex) {
str[index] // p
}
Если бы смещение было 77вместо 7, то ifоператор был бы пропущен.
Зачем нужен String.Index?
Было бы намного проще использовать Intиндекс для строк. Причина, по которой вам нужно создавать новую String.Indexстроку для каждой строки, заключается в том, что символы в Swift не имеют одинаковой длины под капотом. Один символ Swift может состоять из одной, двух или даже более кодовых точек Unicode. Таким образом, каждая уникальная строка должна вычислять индексы своих символов.
Возможно, эту сложность можно скрыть за расширением индекса Int, но я не хочу этого делать. Приятно напоминать о том, что происходит на самом деле.
startIndexбыть что-то еще, кроме 0?