Swift对数组的引用?

时间:2016-03-12 00:01:42

标签: arrays swift

我可能错过了关于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"

4 个答案:

答案 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时行为会发生变化,如下所示:

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,因此它具有复制而非指向的行为。虽然NSArrayNSMutableArray仍然是类(如在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”。这应该适合你。