Swift中Array,Dictionary,Int,String等都是用结构体来实现的,所以这些都是值类型,而Class则是引用类型
值类型
值类型在赋值或者参数传递的时候总会复制自己,Swift标准库中的值类型实现了写时复制功能,每次复制的时候都会共享同一片存储空间,只有真正改变实例数据时才会产生一份副本
import Foundation
var str1="hello world"
var str2=str1
str2+=", xy say"
print(str1)//hello world
print(str2)//hello world, xy say
引用类型
引用类型在赋值或者参数传递的时候都会创建新的引用,而不会复制自己
import Foundation
class Person{
var height=170
var color:String="black"
}
var person1=Person()
var person2=person1
print(person1.height)//170
person2.height=180
print(person1.height)//180
print(person2.height)//180
值类型与引用类型混用
值类型中使用引用类型会增加复杂程度,而引用类型中使用值类型则没有这个问题
当一个值类型包含引用类型,然后发生复制时,在Swift中不会创建新的引用类型实例,这称为浅复制,而深复制则会复制引用类型的实例
class Person{
var height=170
var color:String="black"
init(height:Int,color:String) {
self.height=height
self.color=color
}
}
var person1=Person(height:180,color:"red")
var person2=Person(height:170,color:"blue")
var person3=Person(height:160,color:"white")
var personArray1=[person1,person2,person3]
var personArray2=personArray1
personArray2[0].color = "purple"
print(personArray1[0].color)//purple
print(personArray2[0].color)//purple
相等与同一
- 相等指的是两个实例具有相同的值,用==判断
- 同一则是指的两个实例指向内存中同一个实例,用===判断
- 两个实例如果同一,则必定相等,反之不成立
- 值类型只能判断是否相等
- 引用类型只能判断是否同一,除非使用协议
import Foundation
class Person{
var height=170
var color:String="black"
init(height:Int,color:String) {
self.height=height
self.color=color
}
}
var person1=Person(height:180,color:"blue")
var person2=Person(height:180,color:"blue")
var person3=person1
print(person1 === person2)//false
print(person1 === person3)//true
let value1=1
let value2=1
print(value1 == value2)//true
什么时候用值类型,什么时候用引用类型
- 如果需要确保被赋值或者参数传递时值被复制,则使用值类型
- 如果类型不支持子类继承,那就使用结构体
- 如果类型要表达的行为比较简单,优先考虑使用结构体,之后可以随时改为类
- 其他情况都使用类