Oto rozszerzenie , które pozwoli ci uzyskać dostęp do granic podciągu jako Ints zamiast String.Indexwartości:
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))
}
}
Miej tylko świadomość, że może to prowadzić do dziwności, dlatego Apple zdecydowało się to utrudnić. (Chociaż jest to dyskusyjna decyzja projektowa - ukrywanie niebezpiecznej rzeczy tylko przez utrudnianie jej ...)
Możesz przeczytać więcej w dokumentacji String firmy Apple , ale tldr wynika z faktu, że te „indeksy” są w rzeczywistości specyficzne dla implementacji. Reprezentują one indeksy w ciągu znaków po wyrenderowaniu go przez system operacyjny , więc mogą przechodzić z systemu operacyjnego do systemu operacyjnego w zależności od używanej wersji specyfikacji Unicode. Oznacza to, że dostęp do wartości według indeksu nie jest już operacją działającą w czasie stałym, ponieważ specyfikacja UTF musi zostać przeprowadzona na danych, aby określić właściwe miejsce w ciągu. Te indeksy również nie będą zgodne z wartościami generowanymi przez NSString, jeśli połączysz się z nim, lub z indeksami do bazowych skalarów UTF. Caveat developer.