Qu'est-ce qu'une tranche dans Swift et en quoi diffère-t-elle d'un tableau?
Dans la documentation, la signature de type de l'indice (Range) est la suivante:
subscript(Range<Int>) -> Slice<T>
Pourquoi ne pas 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:
n'a pas trouvé de 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?
La tranche pointe dans le tableau. Aucun point de faire un autre tableau lorsque le tableau existe déjà et la tranche peut simplement décrire la partie souhaitée de celui-ci.
L'addition provoque une contrainte implicite, donc ça marche. Pour que votre mission fonctionne, vous aurait besoin de contraindre:
var list = ["hello", "world"]
var slice: Array<String> = Array(list[0..<list.count])
Note: Cette réponse est heureusement invalide à partir de Swift beta 3, car les tableaux sont maintenant des types à valeur vraie.
@matt est correct, ci-dessus - le 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 est que la tranche agit comme un tableau. Etant donné que dans Swift nous nous attendons à l’immuabilité, il semble dangereux que les valeurs en indice de la tranche puissent changer sans préavis:
println(slice[1]) // "world"
arr[1] = "le monde"
println(slice[1]) // "le monde"
Mais si la matrice sous-jacente change trop radicalement, elle est décrochée:
arr.removeAtIndex(0) // this detaches slice from arr
println(slice) // ["bonjour", "le monde"]
arr[0] = "hola"
println(slice) // ["bonjour", "le monde"]
Les réponses ci-dessus étaient vraies jusqu'à la Bêta 3 (et peuvent changer à nouveau dans les prochaines versions)
Slice agit maintenant comme un tableau, mais comme @matt l’a dit plus haut, c’est en réalité une copie superficielle d’un tableau sous le capot, jusqu’à ce qu’une modification soit apportée. Les tranches (maintenant) voient un instantané des valeurs d'origine,
Notez également que la syntaxe de slice a changé:
[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"]
Cela permet un traitement beaucoup plus uniforme, car il est plus simple (IMHO) de faire python traitement de la liste de styles - filtrer une liste pour en faire une autre.) tableau temporaire pour mapper une tranche. Le nouveau code est maintenant 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 juste, foo est toujours une tranche)
Changements importants, problèmes résolus, - Swift Langue, paragraphe 1
"Array in Swift a été complètement repensé pour avoir une sémantique de valeur complète telle que Dictionnaire et String ... m"