Что такое срез в Swift?
Что такое срез в Swift и как он отличается от массива?
Из документации подпись типа индекса (Range):
subscript(Range<Int>) -> Slice<T>
Почему бы не вернуть еще Array<T>
вместо 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]
Что такое срез?
Ответы
Ответ 1
Нарезка указывает на массив. Нет смысла создавать другой массив, когда массив уже существует, а срез может просто описать желаемую его часть.
Добавление вызывает неявное принуждение, поэтому оно работает. Чтобы ваше задание работало, вам необходимо принудить:
var list = ["hello", "world"]
var slice: Array<String> = Array(list[0..<list.count])
Ответ 2
Примечание.. Этот ответ с радостью недействителен, как и в случае с 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"]
Ответ 3
Резюме:
Ответы выше были достоверными до Beta 3 (и могут снова измениться в будущих выпусках)
Теперь срез действует точно так же, как массив, но, как сказал @matt выше, фактически представляет собой мелкую копию массива под капотом, пока не будет сделано изменение. Срезы (теперь) видят моментальный снимок исходных значений,
Также обратите внимание, что синтаксис среза изменился:
[from..upToButNotIncluding] -> [from..<upToButNotIncluding]
Пример:
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 был полностью переработан, чтобы иметь полноценную семантику, такую как словарь и
Строка... м "