更改数组中struct的值

时间:2014-10-14 22:55:40

标签: arrays swift struct

我想在数组中存储结构,在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'"
}

如果我将结构更改为类,则可以正常工作。任何人都可以告诉我如何更改结构的值。

7 个答案:

答案 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)

如何更改 ArrayStructs

对于每个元素:

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