我仍然不确定struct copy或reference的规则。
我希望在从数组迭代结构对象时改变它: 例如,在这种情况下,我想改变背景颜色 但编译器对我大吼大叫
struct Options {
var backgroundColor = UIColor.blackColor()
}
var arrayOfMyStruct = [MyStruct]
...
for obj in arrayOfMyStruct {
obj.backgroundColor = UIColor.redColor() // ! get an error
}
答案 0 :(得分:34)
struct
是值类型,因此在for
循环中您处理副本。
就像测试一样,你可以试试这个:
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()
}
在这里,您只需枚举索引,并直接访问存储在数组中的值。
希望这有帮助。
答案 1 :(得分:13)
您可以使用Array.indices
来避免ignoring the second value with enumerated()
:
for index in arrayOfMyStruct.indices {
arrayOfMyStruct[index].backgroundColor = UIColor.red
}
答案 2 :(得分:2)
对于Swift 3,请使用enumerated()
方法。
例如:
for (index, _) in arrayOfMyStruct.enumerated() {
arrayOfMyStruct[index].backgroundColor = UIColor.redColor()
}
元组还包含对象的副本,因此您可以使用for (index, object)
来直接访问对象,但由于它是副本,您将无法以这种方式改变数组,并应使用index
这样做。直接引用documentation:
如果您需要每个项目的整数索引及其值,请使用 用于迭代数组的enumerated()方法。对于每一个 在数组中的项目中,enumerated()方法返回一个由元组成的元组 一个整数和项目。
答案 3 :(得分:0)
您正在使用struct
对象,这些对象在使用for in
循环时会复制到局部变量中。数组也是一个struct
对象,因此,如果要对数组的所有成员进行突变,则必须创建由原始对象的修改后的副本填充的原始数组的修改后的副本。
arrayOfMyStruct = arrayOfMyStruct.map { obj in
var obj = obj
obj.backgroundColor = .red
return obj
}
可以通过添加此Array扩展名来简化它。
快捷键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
}
}
}
用法
arrayOfMyStruct.mutateEach { obj in
obj.backgroundColor = .red
}
答案 4 :(得分:-3)
我在一些代码中看到了这个方法,它似乎正在工作
for (var mutableStruct) in arrayOfMyStruct {
mutableStruct.backgroundColor = UIColor.redColor()
}