¿Qué es un segmento en Swift y en qué se diferencia de una matriz?
De la documentación, la firma de tipo del subíndice (Rango) es:
subscript(Range<Int>) -> Slice<T>
¿Por qué no devolver otro en Array<T>
lugar de un Slice<T>
?
Parece que puedo concatenar un segmento con una matriz:
var list = ["hello", "world"]
var slice: Array<String> = [] + list[0..list.count]
Pero esto produce el error:
no se pudo encontrar una sobrecarga para 'subíndice' que acepta los argumentos proporcionados
var list = ["hello", "world"]
var slice: Array<String> = list[0..list.count]
¿Qué es una rebanada?
Nota: Esta respuesta felizmente no es válida a partir de Swift beta 3, ya que las matrices ahora son tipos de valor verdadero.
@matt es correcto, arriba - los
Slice<T>
puntos en la matriz. Eso parece contrario a la forma en que Swift maneja todos los otros tipos de datos con los que estamos trabajando, ya que significa que el valor del segmento puede cambiar incluso si se declara como una constante:var arr = ["hello", "world", "goodbye"] // ["hello", "world", "goodbye"] let slice = arr[0..2] // ["hello", "world"] arr[0] = "bonjour" println(slice) // ["bonjour", "world"]
La peor parte es que el segmento actúa como una matriz. Dado que en Swift tenemos una expectativa de inmutabilidad, parece peligroso que los valores subindicados del segmento puedan cambiar sin previo aviso:
println(slice[1]) // "world" arr[1] = "le monde" println(slice[1]) // "le monde"
Pero si la matriz subyacente cambia demasiado drásticamente, se desengancha:
arr.removeAtIndex(0) // this detaches slice from arr println(slice) // ["bonjour", "le monde"] arr[0] = "hola" println(slice) // ["bonjour", "le monde"]
fuente
let arr = ["hello", "world", "goodbye"]; arr[0] = "bonjour"
. Encontrarás que funciona. Con matrices inmutables, curiosamente, solo el tamaño es inmutable, no el contenido. (Ver "Mutabilidad de colecciones" en The Swift Programming Language )Resumen:
Las respuestas anteriores fueron ciertas hasta Beta 3 (y pueden cambiar nuevamente en versiones futuras)
Slice ahora actúa como una matriz, pero como @matt dijo anteriormente, es efectivamente una copia superficial de una matriz debajo del capó, hasta que se realice un cambio. Los sectores (ahora) ven una instantánea de los valores originales,
También tenga en cuenta que la sintaxis de los segmentos ha cambiado:
Ejemplo:
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"]
Esto permite un procesamiento mucho más uniforme, ya que es más simple (en mi humilde opinión) hacer el procesamiento de listas al estilo Python: filtrar una lista para hacer otra. según la respuesta de Matt antes de Beta 3, tenía que crear una matriz temporal para mapear una porción. El nuevo código ahora es más simple:
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}]
(aunque para ser justos, foo sigue siendo un trozo)
Referencia:
http://adcdownload.apple.com//Developer_Tools/xcode_6_beta_3_lpw27r/xcode_6_beta_3_release_notes__.pdf
Cambios importantes, problemas resueltos, lenguaje rápido, párrafo 1
"Array en Swift se ha rediseñado por completo para tener semántica de valor completo como Dictionary y String ... m"
fuente