Swift学习39:结构体
结构体
Swift
结构体
是构建代码
所用的一种
通用且灵活的构造体
Swift
结构体
是值类型
,通过复制
的方式在代码中传递
,因此它的值是不可修改的
类和结构体对比
Swift 中类和结构体有很多共同点:
- 定义
属性
用于存储值
- 定义
方法
用于提供功能
- 定义
下标脚本
用于访问值 - 定义
初始化器
用于生成初始化值
- 通过
扩展
以增加默认实现的功能
- 符合
协议
以对某类提供标准功能
与结构体相对,类还有如下的 附加
功能:
- class 定义
属性
,必须赋值或包装成Optional。struct 定义属性不需要要赋值 - class 是
引用类型
,浅拷贝。struct 是值类型
,深拷贝。 - class
可以继承
。struct不能继承
。 - class 有
引用计数
,可以多次引用
。struct 没有引用计数 - class 有
类型转换
,允许在运行时检查和解释一个类实例的类型
。struct 没有 - class 有
解构器
允许一个类实例释放任何其所被分配的资源
- struct 分配在
栈
中,系统分配是否内存。class 分配在堆
中,动态分配释放内存 - struct 比 class 更轻量级,
栈
只访问一次拿到数据,堆
访问两次拿到数据(第一次获取指针,第二次获取数据)
作用
结构体可以 定义属性(常量let、变量var)
和 添加方法
,从而 扩展结构体的功能
语法
通过关键字 struct
来定义结构体:
1 | struct 结构体名 { |
定义存储属性
struct 定义存储属性,允许不设置默认值
1 | struct Person { |
实例化
1 | // 实例化 |
延迟存储属性
延迟存储属性的初始值在第一次使用时才进行计算
。声明前面标注
lazy
关键字来表示一个延迟存储属性
lazy
修饰的属性,必须要初始化
示例:
1 | // 延迟存储属性 |
定义计算属性
除了
存储属性
,类
还能定义计算属性
,而它实际并不是存储值
。相反,它提供一个
读取器
和一个可选的设置器
来间接得到和设置其它的属性和值
。类似于OC
的set/get
方法去设值和取值
1 | // 计算属性 |
简写 setter
- 如果一个
计算属性
的设置器
没有为将要被设置的值定义一个名字,那么它将被默认命名为newValue
1 | set { |
简写 getter
- 如果整个
getter
的函数体是一个单一的表达式
,那么getter
隐士返回这个表达式
1 | // 简写 get |
只读计算属性
一个
有读取器
但是没有设置器
的计算属性
就是所谓的只读计算属性
。只读计算属性返回一个值,也可以通过点语法
访问,但是不能被修改为另一个值你必须用
var关键字
定义计算属性(包括只读计算属性)为变量属性,因为它的值不是固定的
。let关键字
只能用于常量属性,用于明确哪些值一旦作为实例初始化就不能更改
1 | // 只读计算属性 |
属性观察者
willSet
会在该值被存储之前被调用
didSet
会在一个新值被存储之后被调用
如果你实现了一个
willSet
观察者,新的属性值会以常量形式参数传递。你可以再你的willSet
实现中为这个参数定义名字。如果你没有为它命名,那么它会使用默认值的名字newValue
如果你实现了一个
didSet
观察者,一个包含旧属性值的常量形式参数将会被传递。你可以为它命名,也可以使用默认值的形式参数名oldValue
。如果你在属性自己的disSet
观察者里给自己赋值,你赋值的新值就会取代刚刚设置的值。
1 | // 属性观察器 |
全局和局部变量
观察属性的能力同样对全局变量和局部变量有效
。全局变量
是定义在任何函数、方法、闭包或者类之外的变量
。局部变量
是定义在函数、方法或闭包环境之中的变量
。
1 | // 全局变量 |
类型属性
struct、enum
中使用static
关键字来定义类型属性
。
1 | // 类型属性 |
struct、enum
中不允许
使用class
关键字来定义类型属性
定义实例方法
实例方法
是属于特定类实例、结构体实例或枚举实例的函数
,提供访问和修改实例属性的方法
每一个类的实例都隐含一个叫做
self的属性
,它完全与实例本身相等。你可以用self
属性在当前实例中调用自身的方法实际上,你不需要经常在代码中写
self
。如果你没有显示地写出self
,swift
会在你方法中使用已知属性或方法的时候假定你调用了当前实例中的属性或者方法例外就是当一个实例方法的形式参数名与实例中某个属性拥有相同的名字的时候。在这种情况下,形式参数名具有优先权,并且调用属性的时候使用更加严谨的方式就很有必要了。你可以使用
self
属性来区分形式参数名和属性名
1 | // 定义方法 |
实例方法 self
1 | // self |
在实例方法中修改属性
struct、enum
是值类型的
,默认情况下,值类型属性不能被修改
你可以选择在
func
关键字前放一个mutating(异变方法)
关键字来指定可以修改属性
1 | // 修改属性 |
在 mutating 方法中赋值给 self
mutating
方法可以指定整个实例给隐含的self
属性
1 | // self |
类型方法
struct、enum
通过在func
关键字前用static
关键字来明确一个类型方法
。
1 | // 类型方法 |
struct、enum
不允许既有static
又有mutating
定义初始化器
1 | // 定义初始化器 |
成员初始化器
如果结构体中没有定义任何初始化器,它会自动获得一个 成员初始化器
1 | struct Size { |
初始化器委托
初始化器可以调用其他初始化器,避免了多个初始化器里冗余代码
1 | struct Name { |
定义下标脚本
类、结构体和枚举
可以定义下标
,它可以作为访问集合、列表或序列号成员元素的快捷方式。你可以使用下标通过索引值来设置或检索值而不需要为设置和检索分别使用实例方法你可以为一个类型
定义多个下标
,并且下标会基于传入的索引值的类型选择合适的下标重载使用。下标没有限制单个维度,你可以使用多个输入形参来定义下标以满足自定义类型的需求下标脚本
允许你通过在实例名后面的方括号内写一个或多个值对该类的实例进行查询。它的语法类似于实例方法和计算属性。使用关键字subscript
来定义下标,并且指定一个或多个输入形式参数和返回类型,与实例方法一样。与实例方法不同的是,下标可以是读写也可以是只读的下标脚本的访问用
[]
1 | // 定义下标脚本 |
- Post title:Swift学习39:结构体
- Post author:张建
- Create time:2023-03-05 17:04:39
- Post link:https://redefine.ohevan.com/2023/03/05/Swift课程/Swift学习39:结构体/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.