
Zastosowano wszystkie poniższe przykłady
var str = "Hello, playground"
Szybki 4
Ciągi zostały dość gruntownie zmienione w Swift 4. Kiedy teraz otrzymujesz podciąg z String, dostajesz z Substringpowrotem typ zamiast a String. Dlaczego to? Ciągi są typami wartości w Swift. Oznacza to, że jeśli użyjesz jednego ciągu, aby utworzyć nowy, należy go skopiować. Jest to dobre dla stabilności (nikt inny nie zmieni tego bez twojej wiedzy), ale złe dla wydajności.
Z drugiej strony podłańcuch jest odniesieniem do oryginalnego ciągu, z którego pochodzi. Oto obraz z dokumentacji ilustrujący to.

Kopiowanie nie jest potrzebne, więc jest znacznie wydajniejsze w użyciu. Wyobraź sobie jednak, że masz dziesięcioznakowy podłańcuch z milionowego ciągu znaków. Ponieważ podłańcuch odwołuje się do ciągu, system musiałby trzymać się całego ciągu tak długo, jak długo znajduje się on w pobliżu. Dlatego za każdym razem, gdy skończysz manipulować swoim podciągiem, przekonwertuj go na ciąg.
let myString = String(mySubstring)
Spowoduje to skopiowanie tylko podciągu, a pamięć zawierająca stary ciąg może zostać odzyskana . Podciągi (jako typ) mają być krótkotrwałe.
Kolejną dużą poprawą w Swift 4 jest to, że ciągi są kolekcjami (ponownie). Oznacza to, że cokolwiek możesz zrobić z kolekcją, możesz zrobić z łańcuchem (użyj indeksów dolnych, iteruj po znakach, filtruj itp.).
Poniższe przykłady pokazują, jak uzyskać podciąg w Swift.
Pobieranie podciągów
Można uzyskać podciąg z ciągu znaków za pomocą indeksów lub szereg innych metod (na przykład prefix, suffix, split). Nadal jednak musisz używać indeksu dla zakresu, String.Indexa nie Intindeksu. (Zobacz moją drugą odpowiedź, jeśli potrzebujesz pomocy.)
Początek łańcucha
Możesz użyć indeksu dolnego (zwróć uwagę na jednostronny zakres Swift 4):
let index = str.index(str.startIndex, offsetBy: 5)
let mySubstring = str[..<index] // Hello
lub prefix:
let index = str.index(str.startIndex, offsetBy: 5)
let mySubstring = str.prefix(upTo: index) // Hello
lub nawet łatwiej:
let mySubstring = str.prefix(5) // Hello
Koniec łańcucha
Korzystanie z indeksów dolnych:
let index = str.index(str.endIndex, offsetBy: -10)
let mySubstring = str[index...] // playground
lub suffix:
let index = str.index(str.endIndex, offsetBy: -10)
let mySubstring = str.suffix(from: index) // playground
lub nawet łatwiej:
let mySubstring = str.suffix(10) // playground
Zauważ, że podczas używania suffix(from: index)musiałem odliczać od końca, używając -10. Nie jest to konieczne przy zwykłym użyciu suffix(x), które po prostu pobiera ostatnie xznaki ciągu.
Zakres w ciągu
Ponownie używamy tutaj indeksów dolnych.
let start = str.index(str.startIndex, offsetBy: 7)
let end = str.index(str.endIndex, offsetBy: -6)
let range = start..<end
let mySubstring = str[range] // play
Konwertowanie SubstringnaString
Nie zapominaj, że kiedy będziesz gotowy do zapisania swojego podciągu, powinieneś przekonwertować go na Stringtak, aby pamięć starego łańcucha mogła zostać wyczyszczona.
let myString = String(mySubstring)
Używasz Introzszerzenia indeksu?
Waham się przed użyciem Introzszerzenia indeksu opartego na indeksie po przeczytaniu artykułu Strings in Swift 3 autorstwa Airspeed Velocity i Ole Begemann. Chociaż w Swift 4 Strings są kolekcjami, zespół Swift celowo nie używał Intindeksów. Nadal jest String.Index. Ma to związek z tym, że znaki Swift składają się z różnej liczby punktów kodowych Unicode. Rzeczywisty indeks musi być jednoznacznie obliczony dla każdego łańcucha.
Muszę powiedzieć, że mam nadzieję, że zespół Swift znajdzie sposób na abstrahowanie String.Indexw przyszłości. Ale dopóki nie zdecyduję się użyć ich interfejsu API. Pomaga mi pamiętać, że manipulacje ciągami znaków to nie tylko proste Intwyszukiwanie indeksów.