Co to jest wycinek w Swift i czym różni się od tablicy?
Z dokumentacji typ podpisu indeksu dolnego (Zakres) to:
subscript(Range<Int>) -> Slice<T>
Dlaczego nie zwrócić innego, Array<T>
a nie Slice<T>
?
Wygląda na to, że mogę połączyć wycinek z tablicą:
var list = ["hello", "world"]
var slice: Array<String> = [] + list[0..list.count]
Ale to daje błąd:
nie można znaleźć przeciążenia dla „indeksu dolnego”, który akceptuje podane argumenty
var list = ["hello", "world"]
var slice: Array<String> = list[0..list.count]
Co to jest plasterek?
Uwaga: na szczęście ta odpowiedź jest nieprawidłowa od wersji Swift beta 3, ponieważ tablice są teraz prawdziwymi typami wartości.
@matt jest poprawne, powyżej -
Slice<T>
punkty w tablicy. Wydaje się to sprzeczne ze sposobem, w jaki Swift obsługuje wszystkie inne typy danych, z którymi pracujemy, ponieważ oznacza to, że wartość wycinka może się zmienić, nawet jeśli jest zadeklarowana jako stała:var arr = ["hello", "world", "goodbye"] // ["hello", "world", "goodbye"] let slice = arr[0..2] // ["hello", "world"] arr[0] = "bonjour" println(slice) // ["bonjour", "world"]
Najgorsze jest to, że wycinek działa jak tablica. Biorąc pod uwagę, że w Swift spodziewamy się niezmienności, wydaje się niebezpieczne, że indeksowane wartości wycinka mogą się zmieniać bez ostrzeżenia:
println(slice[1]) // "world" arr[1] = "le monde" println(slice[1]) // "le monde"
Ale jeśli podstawowa tablica zmieni się zbyt drastycznie, zostaną odłączone:
arr.removeAtIndex(0) // this detaches slice from arr println(slice) // ["bonjour", "le monde"] arr[0] = "hola" println(slice) // ["bonjour", "le monde"]
źródło
let arr = ["hello", "world", "goodbye"]; arr[0] = "bonjour"
. Przekonasz się, że to działa. W przypadku niezmiennych tablic, co dziwne, niezmienny jest tylko rozmiar , a nie zawartość. (Zobacz „Mutability of Collections” w The Swift Programming Language )Podsumowanie:
Powyższe odpowiedzi były prawdziwe aż do Beta 3 (i mogą ulec zmianie w przyszłych wydaniach)
Slice działa teraz jak tablica, ale jak @matt powiedział powyżej, jest faktycznie płytką kopią do tablicy pod maską, dopóki nie zostanie dokonana zmiana. Plasterki (teraz) wyświetlają migawkę oryginalnych wartości,
Zwróć również uwagę, że składnia wycinka uległa zmianie:
Przykład:
var arr = ["hello", "world", "goodbye"] // ["hello", "world", "goodbye"] var arrCopy = arr let slice = arr[0..<2] // ["hello", "world"] arr[0] = "bonjour" arr // ["bonjour", "world", "goodbye"] arrCopy // ["hello", "world", "goodbye"] slice // ["hello", "world"]
Pozwala to na znacznie bardziej jednolite przetwarzanie, ponieważ prostsze jest (IMHO) przetwarzanie list w stylu Pythona - filtrowanie jednej listy, aby utworzyć drugą. zgodnie z odpowiedzią Matta przed Beta 3, trzeba było utworzyć tymczasową tablicę, aby zmapować wycinek. Nowy kod jest teraz prostszy:
class NameNumber { var name:String = "" var number:Int = 0 init (name:String, number:Int) { self.name = name self.number = number } } var number = 1 let names = ["Alan", "Bob", "Cory", "David"] let foo = names[0..<2].map { n in NameNumber(name:n, number:number++) } foo // [{name "Alan" number 1}, {name "Bob" number 2}]
(choć żeby być uczciwym, foo to wciąż kawałek)
Odniesienie:
http://adcdownload.apple.com//Developer_Tools/xcode_6_beta_3_lpw27r/xcode_6_beta_3_release_notes__.pdf
Ważne zmiany, rozwiązane problemy, - Swift Language, akapit 1
„Tablica w języku Swift została całkowicie przeprojektowana, aby mieć pełną semantykę, taką jak Dictionary i String ... m”
źródło