Qu'est-ce qu'une tranche dans Swift et en quoi diffère-t-elle d'un tableau?
D'après la documentation, la signature de type de l'indice (Range) est:
subscript(Range<Int>) -> Slice<T>
Pourquoi ne pas en retourner un autre Array<T>
plutôt qu'un Slice<T>
?
Il semble que je puisse concaténer une tranche avec un tableau:
var list = ["hello", "world"]
var slice: Array<String> = [] + list[0..list.count]
Mais cela donne l'erreur:
Impossible de trouver une surcharge pour 'indice' qui accepte les arguments fournis
var list = ["hello", "world"]
var slice: Array<String> = list[0..list.count]
Qu'est-ce qu'une tranche?
Remarque: Cette réponse est heureusement invalide à partir de Swift beta 3, car les tableaux sont désormais de vrais types de valeurs.
@matt est correct, au-dessus - les
Slice<T>
points dans le tableau. Cela semble contraire à la façon dont Swift gère tous les autres types de données avec lesquels nous travaillons, car cela signifie que la valeur de la tranche peut changer même si elle est déclarée comme constante:var arr = ["hello", "world", "goodbye"] // ["hello", "world", "goodbye"] let slice = arr[0..2] // ["hello", "world"] arr[0] = "bonjour" println(slice) // ["bonjour", "world"]
Le pire, c'est que la tranche agit comme un tableau. Étant donné que dans Swift, nous avons une attente d'immuabilité, il semble dangereux que les valeurs indicées de la tranche puissent changer sans avertissement:
println(slice[1]) // "world" arr[1] = "le monde" println(slice[1]) // "le monde"
Mais si le tableau sous-jacent change trop radicalement, ils sont décrochés:
arr.removeAtIndex(0) // this detaches slice from arr println(slice) // ["bonjour", "le monde"] arr[0] = "hola" println(slice) // ["bonjour", "le monde"]
la source
let arr = ["hello", "world", "goodbye"]; arr[0] = "bonjour"
. Vous trouverez que cela fonctionne. Avec les tableaux immuables, curieusement, seule la taille est immuable, pas le contenu. (Voir «Mutabilité des collections» dans The Swift Programming Language )Sommaire:
Les réponses ci-dessus étaient vraies jusqu'à la bêta 3 (et pourraient changer à nouveau dans les versions futures)
Slice agit maintenant comme un tableau, mais comme @matt l'a dit ci-dessus, est en fait une copie superficielle dans un tableau sous le capot, jusqu'à ce qu'un changement soit apporté. Les tranches (maintenant) voient un instantané des valeurs d'origine,
Notez également que la syntaxe des tranches a changé:
Exemple:
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"]
Cela permet un traitement beaucoup plus uniforme, car il est plus simple (IMHO) de faire un traitement de liste de style python - filtrer une liste pour en créer une autre. selon la réponse de Matt avant la bêta 3, vous deviez créer un tableau temporaire afin de mapper une tranche. Le nouveau code est désormais plus 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}]
(bien que pour être honnête, foo est toujours une tranche)
Référence:
http://adcdownload.apple.com//Developer_Tools/xcode_6_beta_3_lpw27r/xcode_6_beta_3_release_notes__.pdf
Changements importants, problèmes résolus, - Swift Language, paragraphe 1
"Array in Swift a été complètement repensé pour avoir une sémantique pleine valeur comme Dictionary et String ... m"
la source