Ось розширення, яке дозволить вам отримати доступ до меж підрядка як Int
s замість String.Index
значень:
import Foundation
extension StringProtocol {
func countableRange<SearchType: StringProtocol>(
of search: SearchType,
options: String.CompareOptions = [],
range: Range<String.Index>? = nil,
locale: Locale? = nil
) -> CountableRange<Int>? {
guard let trueRange = self.range(of: search, options: options, range: range, locale: locale) else {
return nil
}
let intStart = self.distance(from: startIndex, to: trueRange.lowerBound)
let intEnd = self.distance(from: trueRange.lowerBound, to: trueRange.upperBound) + intStart
return Range(uncheckedBounds: (lower: intStart, upper: intEnd))
}
}
Тільки майте на увазі, що це може призвести до дивацтва, саме тому Apple вирішила зробити це важко. (Хоча це спірне дизайнерське рішення - приховувати небезпечну річ, просто ускладнюючи ...)
Детальніше ви можете прочитати в документації String від Apple , але tldr полягає в тому, що це випливає з того, що ці "індекси" насправді специфічні для реалізації. Вони представляють індекси в рядку після того, як його відтворила ОС , і тому вони можуть переходити від ОС до ОС залежно від того, яка версія специфікації Unicode використовується. Це означає, що доступ до значень за індексом більше не є операцією з постійним часом, оскільки специфікація UTF повинна бути пропущена над даними, щоб визначити правильне місце в рядку. Ці індекси також не будуть узгоджуватися зі значеннями, згенерованими NSString, якщо ви переходите до нього, або з індексами в базових скалярах UTF. Розробник попередження.