Swift - 如何在迭代结构对象时改变它

问题描述 投票:0回答:7

我仍然不确定结构复制或引用的规则。

我想在从数组迭代结构对象时改变它: 例如在这种情况下我想改变背景颜色 但是编译器在对我大喊大叫

struct Options {
  var backgroundColor = UIColor.blackColor()
}

var arrayOfMyStruct = [MyStruct]

...

for obj in arrayOfMyStruct {
  obj.backgroundColor = UIColor.redColor() // ! get an error
}
swift struct copy mutable
7个回答
61
投票

struct
是值类型,因此在
for
循环中,您正在处理一个副本。

作为测试,你可以试试这个:

斯威夫特 3:

struct Options {
   var backgroundColor = UIColor.black
}

var arrayOfMyStruct = [Options]()

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

斯威夫特2:

struct Options {
    var backgroundColor = UIColor.blackColor()
}

var arrayOfMyStruct = [Options]()

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

这里只是枚举索引,直接访问数组中存储的值。

希望这有帮助。


24
投票

您可以使用

Array.indices

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

12
投票

您正在使用

struct
对象,这些对象在使用
for in
循环时被复制到局部变量。数组也是一个
struct
对象,所以如果你想改变数组的所有成员,你必须创建由原始对象的修改副本填充的原始数组的修改副本。

arrayOfMyStructs = arrayOfMyStructs.map { el in
   var el = el
   el.backgroundColor = .red
   return el
}

可以通过添加这个数组扩展来简化

迅捷 4/5

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
        }
     }
}

用法

arrayOfMyStructs.mutateEach { el in
    el.backgroundColor = .red
}

5
投票

对于 Swift 3,使用

enumerated()
方法。

例如:

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

元组还包含对象的副本,因此您可以使用

for (index, object)
代替直接获取对象,但由于它是副本,您将无法以这种方式改变数组,应该使用
index 
这样做。直接引用文档

如果您需要每个项目的整数索引及其值,请使用 enumerated() 方法来迭代数组。对于每个 数组中的项目,enumerated() 方法返回一个由以下内容组成的元组 一个整数和项目。


1
投票

另一种不用每次都写下标表达式的方法

struct Options {
    var backgroundColor = UIColor.black
}

var arrayOfMyStruct = [Options(), Options(), Options()]

for index in arrayOfMyStruct.indices {
    var option: Options {
        get { arrayOfMyStruct[index] }
        set { arrayOfMyStruct[index] = newValue }
    }
    option.backgroundColor = .red
}

0
投票

这是我的示例代码

arrayOfMyStruct.indices.forEach { arrayOfMyStruct[$0].backgroundColor=UIColor.red }

-7
投票

我在一些代码中看到了这个方法,它似乎有效

for (var mutableStruct) in arrayOfMyStruct {
  mutableStruct.backgroundColor = UIColor.redColor()
}
© www.soinside.com 2019 - 2024. All rights reserved.