web-dev-qa-db-fra.com

Swift - Comment muter un objet struct lors d'une itération dessus)

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
}
26
Avner Barr

struct sont des types de valeurs, donc dans la boucle for vous avez affaire à une copie.

Tout comme un test, vous pouvez essayer ceci:

Swift 3:

struct Options {
   var backgroundColor = UIColor.black
}

var arrayOfMyStruct = [Options]()

for (index, _) in arrayOfMyStruct.enumerated() {
   arrayOfMyStruct[index].backgroundColor = UIColor.red
}

Swift 2:

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.

40
Matteo Piombo

Vous pouvez utiliser use Array.indices :

for index in arrayOfMyStruct.indices {
    arrayOfMyStruct[index].backgroundColor = UIColor.red
}
15
emlai

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
}
2
Ondrej Stocek

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.

2
ldoogy