我想在数组中存储结构,在for循环中访问和更改结构的值。
struct testing {
var value:Int
}
var test1 = testing(value: 6 )
test1.value = 2
// this works with no issue
var test2 = testing(value: 12 )
var testings = [ test1, test2 ]
for test in testings{
test.value = 3
// here I get the error:"Can not assign to 'value' in 'test'"
}
如果我将结构更改为类,则可以正常工作。任何人都可以告诉我如何更改结构的值。
答案 0 :(得分:64)
除了@MikeS所说的,请记住结构是值类型。所以在for
循环中:
for test in testings {
将数组元素的副本分配给test
变量。您对其所做的任何更改都仅限于test
变量,而不对数组元素进行任何实际更改。它适用于类,因为它们是引用类型,因此引用而不是值被复制到test
变量。
这样做的正确方法是使用for
索引:
for index in 0..<testings.count {
testings[index].value = 15
}
在这种情况下,您正在访问(并修改)实际的struct元素,而不是它的副本。
答案 1 :(得分:7)
好吧,我将更新我对swift 3兼容性的回答。
当您编程很多时,您需要更改集合内部对象的某些值。在这个例子中,我们有一个struct数组,并给出了一个我们需要改变特定对象值的条件。这在任何开发日都很常见。
我没有使用索引来确定哪个对象必须被修改,而是更喜欢使用if条件,恕我直言更常见。
import Foundation
struct MyStruct: CustomDebugStringConvertible {
var myValue:Int
var debugDescription: String {
return "struct is \(myValue)"
}
}
let struct1 = MyStruct(myValue: 1)
let struct2 = MyStruct(myValue: 2)
let structArray = [struct1, struct2]
let newStructArray = structArray.map({ (myStruct) -> MyStruct in
// You can check anything like:
if myStruct.myValue == 1 {
var modified = myStruct
modified.myValue = 400
return modified
} else {
return myStruct
}
})
debugPrint(newStructArray)
注意所有的让,这种开发方式更安全。
这些类是引用类型,不需要为了更改值而复制一个值,就像结构一样。使用与类相同的示例:
class MyClass: CustomDebugStringConvertible {
var myValue:Int
init(myValue: Int){
self.myValue = myValue
}
var debugDescription: String {
return "class is \(myValue)"
}
}
let class1 = MyClass(myValue: 1)
let class2 = MyClass(myValue: 2)
let classArray = [class1, class2]
let newClassArray = classArray.map({ (myClass) -> MyClass in
// You can check anything like:
if myClass.myValue == 1 {
myClass.myValue = 400
}
return myClass
})
debugPrint(newClassArray)
答案 2 :(得分:2)
这是一个非常棘手的答案。我想,你不应该这样做:
struct testing {
var value:Int
}
var test1 = testing(value: 6)
var test2 = testing(value: 12)
var ary = [UnsafeMutablePointer<testing>].convertFromArrayLiteral(&test1, &test2)
for p in ary {
p.memory.value = 3
}
if test1.value == test2.value {
println("value: \(test1.value)")
}
对于Xcode 6.1,数组初始化将是
var ary = [UnsafeMutablePointer<testing>](arrayLiteral: &test1, &test2)
答案 3 :(得分:2)
如何更改 Array
的 Structs
对于每个元素:
itemsArray.indices.forEach { itemsArray[$0].someValue = newValue }
对于特定元素:
itemsArray.indices.filter { itemsArray[$0].propertyToCompare == true }
.forEach { itemsArray[$0].someValue = newValue }
答案 4 :(得分:0)
我试过安东尼奥的答案似乎很合乎逻辑但令我惊讶的是它不起作用。进一步探索我尝试了以下内容:
struct testing {
var value:Int
}
var test1 = testing(value: 6 )
var test2 = testing(value: 12 )
var testings = [ test1, test2 ]
var test1b = testings[0]
test1b.value = 13
// I would assume this is same as test1, but it is not test1.value is still 6
// even trying
testings[0].value = 23
// still the value of test1 did not change.
// so I think the only way is to change the whole of test1
test1 = test1b
答案 5 :(得分:0)
我最终重新创建了一个新的struct数组,请参阅下面的示例。
func updateDefaultCreditCard(token: String) {
var updatedArray: [CreditCard] = []
for aCard in self.creditcards {
var card = aCard
card.isDefault = aCard.token == token
updatedArray.append(card)
}
self.creditcards = updatedArray
}
答案 6 :(得分:0)
你有足够的好答案。我将从更通用的角度解决这个问题。
作为另一个更好地理解价值类型的例子以及它们被复制的含义:
struct Item {
var value:Int
}
var item1 = Item(value: 5)
func testMutation ( item: Item){
item.value = 10 // cannot assign to property: 'item' is a 'let' constant
}
这是因为项目被复制,当它进入时,它是不可变的 - 为方便起见。
func anotherTest (item : Item){
print(item.value)
}
anotherTest(item: item1) // 5
没有发生突变,所以没有错误
var item2 = item1 // mutable copy created.
item2.value = 10
print(item2.value) // 10
print(item1.value) // 5