简体   繁体   English

Swift对数组的引用?

[英]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. 这实际上只是一个相同的符号,但如果你要做很多这样的事情你可能更喜欢它。

Class

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. 如果您更改其中一个属性值,则两者都会更改,因为它们是相同的。

Struct 结构

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. 它是原件的副本,它们彼此独立。

Array type 数组类型

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 . 虽然NSArrayNSMutableArray留类(如ObjC)等拥有的指点行为class

Making a struct behave like a 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM