Je ne suis toujours pas sûr des règles de copie de structure ou de référence.
Je veux muter un objet struct tout en l'itérant à partir d'un tableau: Par exemple dans ce cas, je voudrais changer la couleur d'arrière-plan mais le compilateur me crie dessus
struct Options {
var backgroundColor = UIColor.blackColor()
}
var arrayOfMyStruct = [MyStruct]
...
for obj in arrayOfMyStruct {
obj.backgroundColor = UIColor.redColor() // ! get an error
}
struct
sont des types de valeurs, donc dans la boucle for
vous avez affaire à une copie.
Tout comme un test, vous pouvez essayer ceci:
struct Options {
var backgroundColor = UIColor.black
}
var arrayOfMyStruct = [Options]()
for (index, _) in arrayOfMyStruct.enumerated() {
arrayOfMyStruct[index].backgroundColor = UIColor.red
}
struct Options {
var backgroundColor = UIColor.blackColor()
}
var arrayOfMyStruct = [Options]()
for (index, _) in enumerate(arrayOfMyStruct) {
arrayOfMyStruct[index].backgroundColor = UIColor.redColor()
}
Ici, vous venez d'énumérer l'index et d'accéder directement à la valeur stockée dans le tableau.
J'espère que cela t'aides.
Vous pouvez utiliser use Array.indices
:
for index in arrayOfMyStruct.indices {
arrayOfMyStruct[index].backgroundColor = UIColor.red
}
Vous travaillez avec des objets struct
qui sont copiés dans une variable locale lorsque vous utilisez for in
boucle. Le tableau est également un objet struct
, donc si vous voulez muter tous les membres du tableau, vous devez créer une copie modifiée du tableau d'origine remplie par des copies modifiées des objets originaux.
arrayOfMyStruct = arrayOfMyStruct.map { obj in
var obj = obj
obj.backgroundColor = .red
return obj
}
Il peut être simplifié en ajoutant cette extension de tableau.
Swift 4
extension Array {
mutating func mutateEach(by transform: (inout Element) throws -> Void) rethrows {
self = try map { el in
var el = el
try transform(&el)
return el
}
}
}
tilisation
arrayOfMyStruct.mutateEach { obj in
obj.backgroundColor = .red
}
Pour Swift 3, utilisez la méthode enumerated()
.
Par exemple:
for (index, _) in arrayOfMyStruct.enumerated() {
arrayOfMyStruct[index].backgroundColor = UIColor.redColor()
}
Le tuple comprend également une copie de l'objet, vous pouvez donc utiliser for (index, object)
à la place pour accéder directement à l'objet, mais comme il s'agit d'une copie, vous ne pourrez pas muter le tableau de cette manière et vous devriez utiliser index
pour le faire. Pour citer directement le documentation :
Si vous avez besoin de l'index entier de chaque élément ainsi que de sa valeur, utilisez plutôt la méthode enumerated () pour parcourir le tableau. Pour chaque élément du tableau, la méthode enumerated () renvoie un Tuple composé d'un entier et de l'élément.