Swift中有两种类型:值类型(Value Type),引用类型(Reference Type)。
1. 值类型
在Swift中,所有的基本类型:整型(Int)、浮点型(Float)、布尔类型(Boolean)、字符串类型(String)、数组(Array)、字典(Dictionary)、元组(Tuple)都是值类型,它们的底层都是以结构体(Struct)的形式实现的,所以结构体(Struct)也是值类型的,另外,枚举(Enum)也属于值类型。
值类型的变量在赋值时是值拷贝,例如:
var numbers:[String] = ["1","2","3"]
var new_numbers = numbers
new_numbers.append("4")
print(numbers)
print(new_numbers)
控制台输出结果:
上面的代码中,变量numbers的值被赋于new_numbers时是值拷贝,从输出结果可以看出,new_numbers添加新元素时,numbers的值并未发生改变。
这里,着重说一下,结构体(Struct)是值类型的,虽然结构体跟类(Class)长得很像。
struct Resolution {
var width = 0
var height = 0
}
var hd = Resolution(width: 1920, height: 1080)
var cinema = hd
cinema.width = 2048
print(hd)
print(cinema)
控制台输出结果:
2. 引用类型
Swift中,类(Class)属于引用类型。与值类型不同,引用类型在被赋予到一个变量、常量或者一个函数时,其值不会被拷贝。因此,引用的是已存在的实例本身而不是其拷贝。
class VideoMode {
var frameRate = 0.0
var name: String?
}
let tenEighty = VideoMode()
tenEighty.name = "1080i"
tenEighty.frameRate = 25.0
以上示例中,声明了一个tenEighty常量,其引用了VideoMode类的新实例,并设置了name为“1080i”,frameRate为25.0 。
下面,我们将tenEighty赋值给alsoTenEighty的新常量,同时对alsoTenEighty的frameRate属性进行修改:
let alsoTenEighty = tenEighty
alsoTenEighty.frameRate = 30.0
此时,我们在控制台打印tenEighty.frameRate 和alsoTenEighty.frameRate,结果为:
因为类是引用类型,所以tenEighty和alsoTenEighty引用的是相同的VideoMode实例。
需要注意的是,tenEighty和alsoTenEighty被声明为常量而不是变量,然而你依然可以改变它们的frameRate属性。因为tenEighty和alsoTenEighty并不“存储”VideoMode实例,而是仅仅是对VideoMode实例的引用,所以改变的是被引用的VideoMode的frameRate属性,而不是引用VideoMode的常量的值。