Что такое срез в Swift и чем он отличается от массива?
Из документации подпись типа нижнего индекса (Диапазон):
subscript(Range<Int>) -> Slice<T>
Почему бы не вернуть другой, Array<T>
а не a Slice<T>
?
Похоже, я могу объединить срез с массивом:
var list = ["hello", "world"]
var slice: Array<String> = [] + list[0..list.count]
Но это дает ошибку:
не удалось найти перегрузку для 'индекса', которая принимает предоставленные аргументы
var list = ["hello", "world"]
var slice: Array<String> = list[0..list.count]
Что такое ломтик?
Примечание: этот ответ, к счастью, недействителен для Swift beta 3, поскольку теперь массивы являются типами истинных значений.
@matt правильный, вверху -
Slice<T>
точки в массиве. Это кажется противоречащим тому, как Swift обрабатывает все другие типы данных, с которыми мы работаем, поскольку это означает, что значение среза может измениться, даже если оно объявлено как константа:var arr = ["hello", "world", "goodbye"] // ["hello", "world", "goodbye"] let slice = arr[0..2] // ["hello", "world"] arr[0] = "bonjour" println(slice) // ["bonjour", "world"]
Хуже всего то, что срез действует как массив. Учитывая, что в Swift у нас есть ожидание неизменности, кажется опасным, что индексированные значения среза могут измениться без предупреждения:
println(slice[1]) // "world" arr[1] = "le monde" println(slice[1]) // "le monde"
Но если базовый массив изменяется слишком резко, они отключаются:
arr.removeAtIndex(0) // this detaches slice from arr println(slice) // ["bonjour", "le monde"] arr[0] = "hola" println(slice) // ["bonjour", "le monde"]
источник
let arr = ["hello", "world", "goodbye"]; arr[0] = "bonjour"
. Вы обнаружите, что это работает. В случае с неизменяемыми массивами, как ни странно, неизменен только размер , а не содержимое. (См. «Изменчивость коллекций» в языке программирования Swift )Резюме:
Вышеупомянутые ответы были верны до Beta 3 (и могут снова измениться в будущих выпусках)
Slice теперь действует так же, как массив, но, как @matt сказал выше, фактически является неглубокой копией массива под капотом, пока не будут внесены изменения. Срезы (сейчас) видят снимок исходных значений,
Также обратите внимание, что синтаксис среза изменился:
Пример:
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"]
Это обеспечивает гораздо более единообразную обработку, поскольку проще (IMHO) выполнять обработку списков в стиле Python - фильтровать один список для создания другого. согласно ответу Мэтта до Beta 3 вам нужно было создать временный массив, чтобы сопоставить срез. Новый код стал проще:
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}]
(хотя, честно говоря, foo по-прежнему кусок)
Справка:
http://adcdownload.apple.com//Developer_Tools/xcode_6_beta_3_lpw27r/xcode_6_beta_3_release_notes__.pdf
Важные изменения, проблемы решены, - Swift Language, параграф 1
«Массив в Swift был полностью переработан, чтобы иметь полноценную семантику, такую как Dictionary и String ... m»
источник