简而言之, 我创建了一个由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背景。
答案 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
的实例,该实例是引用类型。在这种情况下,ref
和anotherRef
都指向同一个对象,因此您这次要修改字典中的数组。