我可能错过了关于swift的重要信息。我有一个包含键/快速数组对的映射。我更改了数组,地图中的数组没有改变。有人可以解释发生了什么吗?谢谢!
var map = [String:[String]]()
var list = [String]()
map["list"] = list //output: "["list": []]\n"
print(map)
list.append("test")
print(list) //output: "["test"]\n"
print(map) //output: "["list": []]\n"
答案 0 :(得分:6)
正如您所知,这些(字典和数组)是value types。因此,一般来说,您正在寻找的技术只是将数组从字典中取出,修改它,然后再将其重新放入:
var map = [String:[String]]()
map["list"] = [String]()
var list = map["list"]!
list.append("test")
map["list"] = list
但是,还有另一种方法:你可以获得一种指向字典内部数组的指针,但前提是你使用的函数带有inout
参数。例如:
var map = [String:[String]]()
map["list"] = [String]()
func append(s : String, inout to arr : [String]) {
arr += [s]
}
append("test", to: &(map["list"]!))
这实际上只是一个相同的符号,但如果你要做很多这样的事情,你可能更喜欢它。
答案 1 :(得分:2)
假设我们在Swift中有一个class
类型:
class MyClass {
var a:Int
init(i:Int) {
a = i
}
}
let aClass = MyClass(i: 10)
var bClass = aClass
bClass.a = 20
aClass.a // 20
aClass.a = 30
bClass.a // 30
这里我们看到指针式行为:aClass和bClass指向同一个对象。如果您更改其中一个属性值,则两者都会更改,因为它们是相同的。
使用struct
时行为会发生变化,如下所示:
struct MyStruct {
var a:Int
init(i:Int) {
a = i
}
}
let aStruct = MyStruct(i: 10)
var bStruct = aStruct
bStruct.a = 20
aStruct.a // 10
使用struct
(和enum
)而不是单个实例和指向该实例的多个指针,当我们将值分配给新实例时,会创建一个新实例。它是原件的副本,彼此独立。
由于Swift数组类型是struct
,因此它具有复制而非指向的行为。虽然NSArray
和NSMutableArray
仍然是类(如在ObjC中),因此具有class
的指向行为。
您已经看过其他人关于inout属性的帖子,您也可以使用计算变量来部分复制指针的行为:
struct MyStruct {
lazy var map = [String:[String]]()
var list:[String] {
mutating get {
if map["list"] == nil {
map["list"] = [String]()
}
return map["list"]!
}
set {
map["list"] = newValue
}
}
}
var mS = MyStruct()
mS.list = ["test"]
mS.map // ["list": ["test"]]
mS.list // ["test"]
在类型实例外部,您可以执行以下操作:
var map = [String:[String]]()
var list = [String]()
var appendToList = { (a:String) in
list.append(a)
map["list"] = list
}
appendToList("test") // list and map["list"] are both updated
答案 2 :(得分:1)
Swift中的数组被定义为结构,即值类型。将另一个变量分配给另一个值类型的变量时,它会创建该第二个变量的副本:
map["list"] = list // store a **copy** of list into map
要查看值和引用类型之间的差异,请将数组更改为其ObjectiveC表兄NSMutableArray
,其为引用类型:
var map = [String: NSMutableArray]()
var list = NSMutableArray()
map["list"] = list
list.addObject("test")
print(map) // ["list": (test)]
答案 3 :(得分:0)
正如Code Different所说,Swift中的数组是结构体,所以你要存储数组的副本。
如果你真的想继续使用Swift数组,我建议先填充数组“list”,然后复制到“map”。这应该适合你。