[英]Swift Object reference to array?
I probably missed an important information about swift. 我可能错过了关于swift的重要信息。 I have a map contains a key / swift array pair.
我有一个包含键/快速数组对的映射。 I changed the array and the array inside the map was not changed.
我更改了数组,地图中的数组没有改变。 Could someone explain what is going on?
有人可以解释发生了什么吗? Thanks!
谢谢!
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"
As you've been told, these (dictionaries and arrays) are value types . 正如您所知,这些(字典和数组)是值类型 。 So in general the technique you're looking for is simply to take the array out of the dictionary, modify it, and put it back in again:
因此,一般来说,您正在寻找的技术只是将数组从字典中取出,修改它,然后再将其重新放入:
var map = [String:[String]]()
map["list"] = [String]()
var list = map["list"]!
list.append("test")
map["list"] = list
However, there's another way: you can get a sort of pointer to the array inside the dictionary, but only if you use a function with an inout
parameter. 但是,还有另一种方法:你可以获得一种指向字典内部数组的指针,但
inout
是你使用带有inout
参数的函数。 For example: 例如:
var map = [String:[String]]()
map["list"] = [String]()
func append(s : String, inout to arr : [String]) {
arr += [s]
}
append("test", to: &(map["list"]!))
That's actually just a notation for the same thing, but if you're going to do a lot of this you might prefer it. 这实际上只是一个相同的符号,但如果你要做很多这样的事情你可能更喜欢它。
Let's suppose we have a type that is a class
in Swift: 假设我们有一个类型是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
Here we see pointer-style behaviour: aClass and bClass are pointing at the same object. 这里我们看到指针式行为:aClass和bClass指向同一个对象。 If you change a property value in one of them then both change, because they are the same.
如果您更改其中一个属性值,则两者都会更改,因为它们是相同的。
The behaviour changes when a struct
is used, as can be seen here: 使用
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
With a struct
(and an enum
) instead of there being a single instance and multiple pointers to that instance, a new instance is created when we assign the value to a new instance. 使用
struct
(和enum
)而不是单个实例和指向该实例的多个指针,当我们将值分配给新实例时,会创建一个新实例。 It is a copy of the original and they are independent of one another. 它是原件的副本,它们彼此独立。
Since the Swift Array type is a struct
it has the behaviour of copying rather than pointing. 由于Swift Array类型是一个
struct
它具有复制而不是指向的行为。 While NSArray
and NSMutableArray
remain classes (as in ObjC) and so have the pointing behaviour of a class
. 虽然
NSArray
和NSMutableArray
留类(如ObjC)等拥有的指点行为class
。
You've already seen others post about inout properties, and you can also use computed variables to partially replicate the behaviour of a pointer: 您已经看过其他人关于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"]
While outside a type instance you might do the following: 在类型实例外部,您可以执行以下操作:
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
Array in Swift is defined as a struct, ie a value type. Swift中的数组被定义为结构,即值类型。 When you assign another variable to another variable of value type, it creates a copy of that second variable:
将另一个变量分配给另一个值类型的变量时,它会创建该第二个变量的副本:
map["list"] = list // store a **copy** of list into map
To see the difference between value and reference type, change your array to its ObjectiveC cousin, NSMutableArray
, which is of reference type: 要查看值和引用类型之间的区别,请将数组更改为其ObjectiveC cousin,
NSMutableArray
,它是引用类型:
var map = [String: NSMutableArray]()
var list = NSMutableArray()
map["list"] = list
list.addObject("test")
print(map) // ["list": (test)]
As Code Different says, Arrays in Swift are structs, so you are storing a copy of the array. 正如Code Different所说,Swift中的数组是结构,所以你要存储数组的副本。
If you really want to keep using Swift arrays, I recommend to fill the array "list" first and then copy to "map". 如果你真的想继续使用Swift数组,我建议先填充数组“list”,然后复制到“map”。 That should work for you.
这对你有用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.