Ответ 1
Во всех следующих примерах используйте
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
полезен, чтобы убедиться, что смещение не приводит к тому, что индекс выходит за пределы. Это ограничивающий индекс. Так как смещение может превышать предел, этот метод возвращает Необязательный. Он возвращает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, но я не хочу этого делать. Хорошо помнить о том, что на самом деле происходит.