Swift引用与数组和字典的值

时间:2015-10-10 22:21:51

标签: arrays swift dictionary

简而言之, 我创建了一个由Integer和一个String数组组成的对象。 我在整数和数组中放了一些东西 我将对象放入字典中 我获得了对该对象的新引用并尝试追加到该数组。这是它失败的地方

//: Playground - noun: a place where people can play

class IdAndArray {
    var id: Int = 0
    var stringArray:[String] = [String]()
}

var dict:[Int:IdAndArray] = [Int:IdAndArray]()

var testRec = IdAndArray()
testRec.id = 1
testRec.stringArray.append("1 line")

dict[56] = testRec

var ref = (dict[56]?.stringArray)!
print(ref.count) // 1
ref.append("2 line")

var anotherRef = (dict[56]?.stringArray)!
print(anotherRef.count) // 1 instead of 2???

我怀疑这可能与此有关: Implementing a multimap in Swift with Arrays and Dictionaries

我也怀疑它与选项有关,但我正在强行解开!

为了记录,我来自java背景。

1 个答案:

答案 0 :(得分:2)

Swift数组和字典是 value 类型。当您将变量中的一个分配给另一个变量时,您将复制原始变量。

所以当你这样做时:

var ref = (dict[56]?.stringArray)!

ref是数组的全新副本,而不是字典中的副本,因此修改它对字典中的原始副本没有影响。

相反,如果你做了:

dict[56]?.stringArray.append("2 line")

然后你就会修改字典中的副本。

注意:实际上,在修改其中一个副本之前,Swift不会复制该数组。这是在幕后完成的,以避免不必要的复制并保持快速。复制逻辑上会在您分配时立即发生,但在您开始修改其中一个副本之前,您不会注意到差异,因此Swift会延迟复制,直到重要为止。

现在考虑对您的代码进行此更改:

var ref = dict[56]!
print(ref.stringArray.count) // 1
ref.stringArray.append("2 line")

var anotherRef = dict[56]!
print(anotherRef.stringArray.count) // 2 this time!!!

此处,ref指向class的实例,该实例是引用类型。在这种情况下,refanotherRef都指向同一个对象,因此您这次要修改字典中的数组。