结构和类
Swift不要求为自定义结构和类创建单独的接口和实现文件。在Swift中,在单个文件中定义结构或类,并且该类或结构的外部接口自动可供其他代码使用。
比较结构和类
Swift中的结构和类的共同点:
- 定义存储值的属性
- 定义提供功能的方法
- 定义下标以使用下标语法提供对其值的访问
- 定义初始化程序以设置其初始状态
- 扩展以扩展其功能,超越默认实现
- 符合协议以提供某种标准功能
类具有结构不具备的其他功能:
- 继承使一个类能够继承另一个类的特性
- 类型转换使您可以在运行时检查和解释类实例的类型
- Deinitializers允许类的实例释放它已分配的任何资源
- 引用计数允许对类实例的多个引用
定义语法
使用struct关键字和带有class关键字来引入结构和类。两者都将它们的整个定义放在一对括号中:
struct Resolution {
var width = 0
var height = 0
}
class VideoMode {
var resolution = Resolution()
var interlaced = false
var frameRate = 0.0
var name: String?
}
结构和类实例
结构和类都使用初始化器语法用于新实例。最简单的初始化语法形式是使用类或结构的类型名称,后跟空括号,这将创建类或结构的新实例,并将所有属性初始化为其默认值:
let someResolution = Resolution()
let someVideoMode = VideoMode()
访问属性
可以使用点语法访问实例的属性。在点语法中,在实例名称后面立即写入属性名称,用句点(.)分隔,不带任何空格。也可以使用点语法为变量属性分配新值:
someVideoMode.resolution.width = 10
print(someVideoMode.resolution.width)
结构类型的成员初始化器
所有结构都有一个自动生成的成员初始化程序,可以使用它初始化新结构实例的成员属性。可以通过名称将新实例的属性的初始值传递给成员初始值设定项:
let vga = Resolution(width: 640, height: 480)
与结构不同,类实例不接收默认的成员初始值设定项。
结构和枚举是值类型
结构和枚举都是Swift中的值类型。这意味着您创建的任何结构和枚举实例以及它们作为属性的任何值类型在代码中传递时始终会被复制:
let hd = Resolution(width: 1920, height: 1080)
var cinema = hd
cinema.width = 10
print(hd.width)
print(cinema.width)
/*
打印结果:
1920
10
*/
类是引用类型
值类型不同,引用类型在分配给变量或常量时或者传递给函数时不会被复制。而不是副本,使用对同一现有实例的引用:
let otherVideoMode = someVideoMode
otherVideoMode.resolution.width = 7
print(someVideoMode.resolution.width)
print(otherVideoMode.resolution.width)
/*
打印结果:
7
7
*/
身份运算符
因为类是引用类型,所以多个常量和变量可以在后台引用同一个类的单个实例。(对于结构和枚举却不一样,因为它们在分配给常量或变量或传递给函数时总是被复制。)
判断两个常量或变量是否完全引用类的相同实例。为了实现这一点,Swift提供了两个身份运算符:
- (===)相同
- (!==)不同
使用这些运算符检查两个常量或变量是否引用同一个实例:
if otherVideoMode === someVideoMode {
print("otherVideoMode与someVideoMode相同")
} else {
print("otherVideoMode与someVideoMode不相同")
}
/*
otherVideoMode与someVideoMode相同
*/
指针
引用某个引用类型的实例的Swift常量或变量类似于C中的指针,但它不是指向内存中地址的直接指针,并且不需要编写星号(*)来指示你正在创建一个参考。相反,这些引用的定义与Swift中的任何其他常量或变量一样。