这是我参与更文挑战的第10天,活动详情查看: 更文挑战
结构体和类非常相似,它们都是程序中代码构建块。在Swift中,自定义的结构体和类不需要创建单独的.h和.m文件,可以直接在单个文件中定义结构体和类,通过Swift提供的额外接口,实现类和结构体可以在其他代码中使用
结构体和类的对比
- 结构体和类有很多共同点
- 定义属性用于存储值
- 定义方法用于提供功能
- 定义下标可以使用下标语法来访问实例所包含的值
- 定义初始化方法用于设置初始化值
- 通过扩展可以增加默认实现的功能
- 通过协议可以提供某种标准功能
- 与结构体相比,类还有其他功能
- 继承允许一个类继承另一个类的特征
- 类型转换允许在运行时检查和解释一个类实例的类型
- 析构器允许一个类实例释放任何其所被分配的资源
- 引用计数允许对一个类的多次引用
注意:
结构体总是通过被复制的方式在代码中传递,不使用引用计数
结构体和类的定义
-
类的定义用关键字
class,结构体的定义用关键字structclass Student { var name = "" var age = 0 } struct Teacher { var name = "" var age = 0 } -
结构体和类实例
结构体和类创建新实例,最简单的初始化语法是使用结构体或类的类型名称,后面跟空括号(
())。其中所有属性都初始化为其默认值。class Student { var name = "" var age = 0 } struct Teacher { var name = "" var age = 0 } let student = Student() let teacher = Teacher() -
属性访问
使用点语法(
.)访问实例的属性class Student { var name = "" var age = 0 } struct Teacher { var name = "" var age = 0 } let student = Student() var teacher = Teacher() student.name = "student Li" teacher.name = "teacher wang" print(student.name) print(teacher.name) log: student Li teacher wang -
结构体类型的成员初始化方法
所有结构体会自动生成一个初始化方法,用于初始化结构体中的属性(类没有此功能)
let teacher = Teacher.init(name: "teacher wang", age: 50)
结构体是值类型
Swift中,整数(Int)、浮点数(float)、布尔值(bool)、字符串(string)、数组(array)和字典(dictionary)都是值类型,这些类型底层实现都是基于结构体,所有结构体是值类型。当结构体被赋予给一个变量、常量或被传递给一个函数时,其值都是被拷贝的
struct Teacher {
var name = ""
var age = 0
}
let terW = Teacher(name: "teacher wang", age: 30)
var terL = terW
terL.name = "teacher Li"
//通过log证明terW和terL其中任何一个修改都不会影响另一个
print(terW.name)
print(terL.name)
log:
teacher wang
teacher Li
因为 Teacher 是一个结构体,所以 terL 的值其实是 terW 的一个拷贝副本,而不是 terW 本身。尽管 terW 和 terL 都有着相同的 name 和 age,但其实它们是两个完全不同的实例
类是引用类型
引用类型在被赋予到一个变量、常量或者被传递到一个函数时,其值不会被拷贝。因此,引用的是已存在的实例本身而不是其实例的拷贝
class Student {
var name = ""
var age = 0
}
let stuW = Student()
stuW.name = "student Wang"
let stuL = stuW
stuL.name = "student Li"
//因为类是引用类型,所以stuW和stuL实际上引用的是相同的Student实例
print(stuW.name)
print(stuL.name)
log:
student Li
student Li
注意:
stuW 和 stuL 被声明为常量而不是变量,但是,依然可以改变stuW.name 和 stuL.name,因为 stuW 和 stuL 这两个常量的值并未改变。它们并不存储这个 Student 实例,而是指向 Student 的实例。所以,改变的是被引用的 Student 的 name 属性,而不是引用Student 的常量的值
身份运算符
-
因为类是引用类型,有可能有多个常量和变量同时指向同一个类的实例。(对于结构体和枚举来说,这并不成立。因为它们作为值类型,在被赋予到常量、变量或者传递到函数时,其值总是会被拷贝。)
-
判断两个常量或者变量是否引用同一个类实例,使用相同(
===)或不相同(!==)
class Student {
var name = ""
var age = 0
}
let stuW = Student()
let stuL = stuW
stuL.name = "student Li"
if stuW === stuL {
print("stuW 和 stuL 是相同的Student实例")
}
log:
stuW 和 stuL 是相同的Student实例