定义
- 类定义(通过关键字
class
),结构体定义(通过关键字struct
)
class Student: NSObject {
var name = ""
var age = 0
}
struct Teacher {
var name = ""
var age = 0
}
- 类和结构体实例
let student = Student()
let teacher = Teacher()
- 所有结构体会自动生成一个构造器,用于初始化结构体中的属性(类没有此功能)
let ter = Teacher(name: "teacher", age: 30)
- 属性访问
student.name = "student"
teacher.name = "teacher"
print(student.name)
print(teacher.name)
结构体是值类型
值类型被赋予给一个变量、常量或被传递给一个函数的时,其值会被拷贝(在 Swift 中,所有的基本类型:整数、浮点数、布尔值、字符串、数组和字典,都是值类型)
代码语言:javascript复制struct Teacher {
var name = ""
var age = 0
}
let ter = Teacher(name: "teacher", age: 30)
//因为Teacher是一个结构体,所以ter1的值其实是ter的一个拷贝副本,而不是ter本身。尽管ter和ter1有着相同的name和age,但其实它们是两个完全不同的实例
var ter1 = ter
ter1.name = "good teacher"
//通过log证明ter和ter1其中任何一个修改都不会影响另一个
print(ter.name) //teacher
print(ter1.name) //good teacher
类是引用类型
引用类型在被赋予到一个变量、常量或者被传递到一个函数时,其值不会被拷贝。因此,引用的是已存在的实例本身而不是其拷贝
代码语言:javascript复制class Student: NSObject {
var name = ""
var age = 0
}
let stu = Student()
stu.name = "good student"
//因为类是引用类型,所以stu1和stu实际上引用的是相同的Student实例
let stu1 = stu
stu1.name = "bad student"
print(stu.name) //bad student
print(stu1.name) //bad student
注意: stu
和stu1
被声明为常量而不是变量。但是,依然可以改变stu.name
和stu1.name
,因为stu
和stu1
这两个常量的值并未改变。它们并不存储这个Student
实例,而是指向Student
的实例。所以,改变的是被引用的Student
的name
属性,而不是引用Student
的常量的值
恒等运算符
因为类是引用类型,有可能有多个常量和变量同时指向同一个类的实例。(对于结构体和枚举来说,这并不成立。因为它们作为值类型,在被赋予到常量、变量或者传递到函数时,其值总是会被拷贝。)
能够判定两个常量或者变量是否引用同一个类实例,使用===
和!==
if stu === stu1 {
print("same Student instance")
}
类和结构体对比
Swift 中类和结构体有很多共同点
- 定义属性用于存储值
- 定义方法用于提供功能
- 定义下标可以使用下标语法来访问实例所包含的值
- 定义构造器用于生成初始化值
- 通过扩展可以增加默认实现的功能
- 通过协议可以提供某种标准功能
与结构体相比,类还有如下的附加功能
- 继承允许一个类继承另一个类的特征
- 类型转换允许在运行时检查和解释一个类实例的类型
- 析构器允许一个类实例释放任何其所被分配的资源
- 引用计数允许对一个类的多次引用
注意
结构体总是通过被复制的方式在代码中传递,不使用引用计数