Swift开发——存储属性与计算属性

简介: Swift推荐使用结构体进行开发,结构体支持属性和方法,且作为值类型。结构体属性包括存储属性(如radius)和计算属性(如r),计算属性不存储值,类似方法。结构体用`struct`定义,命名遵循大驼峰规则。实例名遵循小驼峰规则。属性可在结构体中任意位置定义,静态属性用`static`。存储属性可为`lazy`实现懒加载。结构体实例通过`.`访问属性和方法,静态属性和方法用`结构体名.`访问。计算属性可读写,可通过`get`和`set`定义。程序段1展示了结构体Point和Circle的属性和方法,包括私有属性、只读计算属性、可读写计算属性及`mutating`方法。

image.png


Swift语言开发者建议程序设计者多用结构体开发应用程序。在Swift语言中,结构体具有了很多类的特性(除类的与继承相关的特性外),具有属性和方法,且为值类型。所谓的属性是指结构体中的变量或常量,所谓的方法是指结构体中的函数。在结构体中使用属性和方法是因为:①匹别于结构体外部定义的变量和常量;②从面向对象程序设计的角度,结构体对应着现实世界的一个客观物体,描述这个物体的性质需要用到它的属性和方法;③结构体定义的常量或变量称为实例,实例内部的变量或常量成员称为属性,实例内部的函数成员称为方法,这种称谓比常规含义的变量、常量和函数更具有意义。

定义结构体需使用关键字struct,结构体名建议使用“大骆驼命名法”,即首字母大写且其中的完整英文单词的首字母也大写。结构体定义的实例名建议使用“小骆驼命名法”,即首字母小写且其中的完整英文单词的首字母大写。结构体是一种类型,其中定义的属性和方法的位置可任意放置,可以先定义属性,再定义方法;也可以先定义方法,再定义属性。典型的结构体定义形式如下:

image.png


上述代码定义了一个结构体类型,名称为Circle,具有一个属性radius和一个方法area。一般地,在结构体中定义属性时需要为属性赋初始值,或者使用初始化器为结构体的各个属性赋初始值。属性分为两种,一种为存储类型的属性,如上述的radius属性;另一种为计算类型的属性,这种属性的行为类似于方法,但是形式是属性。结构体为值类型,如果结构体中定义的方法修改了其中的属性,需要使用关键字mutating修饰该方法,这种方法将为属性创建临时存储空间,待方法执行完后,将临时存储空间的值赋回给需要修改的属性。

结构体定义的变量或常量称为实例,实例调用属性和方法时使用“实例.属性”或“实例.方法(实际参数列表)”的形式。除了属于实例的属性和方法外,还可以定义属于结构体的属性和方法,借助static关键字定义,使用形式“结构体名.属性”或“结构体名.方法(实际参数列表)”访问这类属性和方法。
# 01、存储属性与计算属性
在结构体中,属性有以下三种类型:

(1) 使用static定义的静态属性,称为结构体属性,这类属性采用“结构体名.结构体属性名”的方式访问,如程序段5-9的第26行所示;

(2) 存储属性,又可称为动态属性,在结构体中定义的常量和变量均属于存储属性,存储属性为实例属性,采用“实例名.存储属性名”的方式访问;

(3) 计算属性,也属于实例属性,采用“实例名.计算属性名”的方式访问,但是计算属性本身不保存属性值,与存储属性不同之处在于在定义计算属性后添加一对“{ }”,在其中添加get方法和set方法(至少要添加get方法),依次用于获取存储属性值或设置存储属性值。

对于存储属性:①当使用private修饰时将变成私有存储属性,这类私有存储属性只能借助计算属性间接访问,不能借助实例访问,从而实现了数据“封装”特性;②当使用lazy修饰时将变成惰性存储属性,这类惰性存储属性必须为变量类型,当它被首次使用时才初始化,即如果惰性存储属性只定义了但没有使用,则该属性不会占用存储空间。

程序段1详细介绍了存储属性、计算属性和私有存储属性的用法。

程序段1结构体的属性用法实例

image.png


image.png


程序段1的执行结果如图1所示。

image.png


■ 图1 程序段1的执行结果

下面结合图1介绍程序段1。在程序段1中,第3~6行定义了结构体Point,具有两个存储属性x和y。

第7~34行定义结构体Circle。其中第9行“var radius=1.0”定义存储属性radius,并赋初值为1.0。一般地,在结构体内定义存储属性时需给它们赋初值。第10~20行定义了计算属性r,将其代码再次罗列如下:

image.png


计算属性r更像是一个方法,具有“{ }”括起来的可执行代码。其中,第12~15行为get方法,这是一种程序员约定的名称,因为这种方法形如“get{ }”,get方法用于返回结构体中某个设定的存储属性的值,这里第14行返回存储属性radius的值,即读取r相当于读取radius。第16~19行为set方法,这也是一种程序员约定的名称,因为这种方法形式“set{ }”,set方法用于向某个选定的存储属性赋值,这里第18行向radius赋值,其中,newValue为关键字,自动保存赋给r的值,因此,向r赋值(即写r)就是向radius赋值(即写radius)。注意:①如果计算属性只有get方法,则去掉set部分,同时,get和“{ }”也可省略,如第22~25行的计算属性c,此时的计算属性为只读属性;②计算属性可以只有get方法,称为只读属性;可以同时有get方法和set方法,称为可读可写属性;但是不能只有set方法,即没有只写属性;③在set方法中可以使用newValue关键字,用于表示赋给计算属性的值,也可以自定义该量,例如第16~19行的代码可以替换为下述代码:

image.png


这里使用了自定义的val变量,此处无须指定数据类型,而是根据计算属性r的类型自动推断数据类型。

第21行“private var center=Point(x:0, y:0)”定义私有存储属性center,这类属性只能借助计算属性访问,同时这类属性可被结构内的其余属性和方法使用,但不能被结构体外部的方法调用,结构体定义的实例也不能访问这类属性。

第22~25行定义一个计算属性c,其代码再次罗列如下:

image.png


这里计算属性c为一个只读属性,省略了get和“{ }”,返回center的值,即读取c相当于读取center。

第26~29行定义了函数moveTo,使用了mutating关键字,因为该函数将修改私有存储属性center的值。第28行“center=point”将参数point赋给私有存储属性center。

第30~33行定义了函数area,返回值为Double类型,函数返回圆的面积。第32行“return 3.14rr”使用了计算属性r,因为计算属性r为可读可写属性,这里读取r相当于读取radius。

第36行“var circle=Circle()”定义结构体实例circle。第37行“circle.r=5.0”将5.0赋给实例circle的计算属性r,计算属性r并不保存值,其内部将5.0赋给存储属性radius。第38行“print("radius=\(circle.r)")”输出存储属性radius的值,得到“radius=5.0”。第39行“circle.moveTo(point:Point(x:3.0, y:4.0))”调用moveTo方法将圆心移动到点(3.0, 4.0)处。第40行“print("Circle at (\(circle.c.x),\(circle.c.y))",terminator:" ")”和第41行“print("with area:\(String(format:"%5.2f",circle.area()))")”联合输出“Circle at (3.0,4.0) with area:78.50”,其中,第40行通过只读的计算属性c,获取圆心坐标。

目录
相关文章
|
7天前
|
存储 Swift 索引
Swift开发——索引器扩展
扩展用于向已存在的类型(例如,类、结构体、枚举和协议等)中添加新的功能,扩展甚至可以向系统类型(包括无法查阅代码的类型)中添加新的功能,但是扩展不能覆盖原类型中已有的方法,扩展也不能向类中添加新的存储属性。
28 6
Swift开发——索引器扩展
|
8天前
|
存储 Swift
Swift开发——属性检查器
Swift中的属性检查器(willSet, didSet)允许在设置存储属性值前后执行代码。在类`Circle`中,属性`radius`使用属性观察器:willSet在赋值前检查值,若值为负则打印警告;didSet在赋值后比较新旧值,根据变化输出相应信息。在实例`c`中,`radius`从-5变为0时,输出“Input value is negative.”和“The circle gets smaller.”;从0变为10时,输出“Input value is normal.”和“The circle gets larger.”。
11 4
Swift开发——属性检查器
|
10天前
|
Swift C++ 索引
Swift开发——简单函数实例
函数是编程的基础,用于封装特定功能的代码。它们有关键词func、函数名、参数列表(可为空)和返回类型。多返回值可通过元组、数组、inout参数或可选类型实现。例如,返回元组 `(value1, value2)`,数组 `[value1, value2]` 或使用可选数组 `[[Double]]?`。函数可以作为其他函数的参数,类似闭包或Lambda表达式。在Swift中,示例展示了通过元组、带索引的元组、数组和可选类型返回多个值的函数。还演示了如何使用inout参数交换变量值。
24 5
Swift开发——简单函数实例
|
7天前
|
存储 Swift
Swift开发——弱占用
Swift的自动引用计数(ARC)管理类实例内存,通过强引用保持实例存活。当出现强引用循环时,可使用`weak`关键字创建弱引用,避免阻止实例释放。弱引用在不再被强引用时导致对象立即释放。示例中,添加`weak`至`author`和`book`变量防止引用循环,使得两者析构器均执行,释放内存。图2展示了弱引用结构,当解除所有强引用后,ARC自动释放实例,调用析构器。
15 1
Swift开发——弱占用
|
10天前
|
存储 算法 Swift
Swift开发——循环执行方式
Swift语言中的循环主要包括`for-in`和`while`结构。`for-in`适用于遍历数字区间、字符串和字典,支持使用`stride`函数定制步进。字典遍历时,可以用二元元组`(k, v)`访问键值对。`while`循环有标准形式和`repeat-while`形式,确保至少执行一次循环体。程序示例展示了`for-in`和不同`while`结构的用法,包括计算阶乘、奇数和、加密字符串以及最大公约数和最小公倍数。
13 0
Swift开发——循环执行方式
|
12天前
|
Swift 索引
Swift开发——元组
Swift中的元组是一种数据结构,用于组合不同类型的值。它们不是独立的数据类型,而是以有序序列形式存在,用圆括号括起,元素间用逗号分隔。元组可以有任意数量和类型的元素,可变性取决于其定义。常用于函数返回多个值。示例代码展示了元组的创建、访问、解包及赋值。元组可以通过标签来标识元素,支持嵌套和比较。在函数返回值和并行赋值场景中,元组特别有用。
24 0
Swift开发——元组
《从零开始学Swift》学习笔记(Day 33)——属性观察者
<span style="font-family:宋体;font-size: 14pt; mso-ascii-font-family: Arial; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Arial; mso-bidi-font-family: Ari
1188 0
|
1月前
|
安全 编译器 Swift
IOS开发基础知识: 对比 Swift 和 Objective-C 的优缺点。
IOS开发基础知识: 对比 Swift 和 Objective-C 的优缺点。
144 2
|
1月前
|
设计模式 前端开发 Swift
使用Swift进行iOS应用开发:深入探索与最佳实践
【5月更文挑战第24天】探索Swift在iOS开发中的深度应用与最佳实践。Swift以其简洁语法、类型安全、面向对象、高性能及与Objective-C的互操作性脱颖而出。使用Xcode设置开发环境,学习Swift语法,创建并设计项目,编写业务逻辑,同时进行调试和测试。遵循MVC模式,利用SwiftUI、并发特性,并注重内存管理,持续学习新工具和技术,以实现高质量应用开发。

相关课程

更多