swift 程序员iOS开发

swift的值类型与inout

2016-07-16  本文已影响206人  八条8tiao

1、什么是值类型

值类型与引用类型相对,值类型的数据特征是,每一个内存实例都会有一份数据copy。在swift语言中,用struct定义的类型都是值类型,这包括了基本数据类型(Int,String,Double,Float),集合类型(Array,Dictionary,Set)等。值类型在赋值和传递的过程中,会表现出copy数据的性质。

struct Point {
    var x = 0
    var y = 0
}

var point1 = Point()
var point2 = point1

我们定义两个值类型的变量point1、point2,当我们使用point1对point2进行赋值的时候,理论上编译器会创建point2对象,并将point1的数据进行一次copy赋值给point2。如果我们修改了point2的内容,我们会发现point1的内容并没有发生变化。

point2.x = 1
print(point2.x) // 1
print(point1.x) // 0, 对point2的修改不会影响point1的内容

2、值类型的优缺点

编译器可以将copy操作延时到不得不进行copy的时候再进行操作(比如常常被提到的“写时拷贝”),更进一步来说,当一个结构体不要求在内存空间中连续存放的话,那么当发生“写时copy”的时候,编译器则完全只处理脏数据的copy,而继续共享相同内容的数据。

let array = [1,2,3,4,5]
array.append(6) // error!!!!!!!

如果array是一个引用类型,let的声明只能限制array不可以再指向其它内容,但let无法限制我们在array所指向的对象中新增内容(既在数据中新增内容)。但此时array是一个值类型,swift编译器保证用let修饰过的值类型不可变,从而将不变性的语义更加完整。

3、inout

我们现在已经知道,值类型在传递的过程中会进行数据的copy,那么显而易见的是下面改变x的值是不会成功的

var x = 10
func changeX(x: Int) {
    x + = 10
}

changeX(x)
print(x) // 10 x的值不会发生改变

如果我们希望x的值可以被改变,那么我们必须使用引用的方式来传递x。这时候我们就需要使用inout,当我们使用inout的时候,编译器不论当前struct的存放状态如何,都一定会把结构体放入一个连续的内存空间中,并将地址作为参数进行传递。

var x = 10
func changeX(x: inOut Int) { // swift3.0改变了inOut修饰符的位置
    x + = 10
}

changeX(x)
print(x) // 20 x的值发生了改变
上一篇 下一篇

猜你喜欢

热点阅读