Swift 结构体和类
结构体和类作为一种通用而又灵活的结构,成为了人们构建代码的基础。你可以使用定义常量、变量和函数的语法,为你的结构体和类定义属性、添加方法。
与其他编程语言所不同的是,Swift 并不要求你为自定义的结构体和类的接口与实现代码分别创建文件。你只需在单一的文件中定义一个结构体或者类,系统将会自动生成面向其它代码的外部接口。
注意
通常一个类的实例被称为对象。然而相比其他语言,Swift 中结构体和类的功能更加相近,本章中所讨论的大部分功能都可以用在结构体或者类上。因此,这里会使用实例这个更通用的术语。
结构体和类对比
Swift 中结构体和类有很多共同点。两者都 可以:
- 定义属性用于存储值
- 定义方法用于提供功能
- 定义下标操作用于通过下标语法访问它们的值
- 定义构造器用于设置初始值
- 通过扩展以增加默认实现之外的功能
- 遵循协议以提供某种标准功能
更多信息请参见 属性、方法、下标、构造过程、扩展 和 协议。
与结构体相比,类还有如下的附加功能:
- 继承允许一个类继承另一个类的特征
- 类型转换允许在运行时检查和解释一个类实例的类型
- 析构器允许一个类实例释放任何其所被分配的资源
- 引用计数允许对一个类的多次引用
更多信息请参见 继承、类型转换、析构过程 和 自动引用计数。
类支持的附加功能是以增加复杂性为代价的。作为一般准则,优先使用结构体,因为它们更容易理解,仅在适当或必要时才使用类。实际上,这意味着你的大多数自定义数据类型都会是结构体和枚举。更多详细的比较参见 在结构和类之间进行选择。
注意
类和 actors 共享很多特性。更多信息请参见 并发。
类型定义的语法
结构体和类有着相似的定义方式。你通过 struct
关键字引入结构体,通过 class
关键字引入类,并将它们的具体定义放在一对大括号中:
struct SomeStructure {
// 在这里定义结构体
}
class SomeClass {
// 在这里定义类
}
注意
每当你定义一个新的结构体或者类时,你都是定义了一个新的 Swift 类型。请使用
UpperCamelCase
这种方式来命名类型(如这里的SomeClass
和SomeStructure
),以便符合标准 Swift 类型的大写命名风格(如String
,Int
和Bool
)。请使用lowerCamelCase
这种方式来命名属性和方法(如frameRate
和incrementCount
),以便和类型名区分。
以下是定义结构体和定义类的示例:
struct Resolution {
var width = 0
var height = 0
}
class VideoMode {
var resolution = Resolution()
var interlaced = false
var frameRate = 0.0
var name: String?
}
在上面的示例中定义了一个名为 Resolution
的结构体,用来描述基于像素的分辨率。这个结构体包含了名为 width
和 height
的两个存储属性。存储属性是与结构体或者类绑定的,并存储在其中的常量 或变量。当这两个属性被初始化为整数 0
的时候,它们会被推断为 Int
类型。
在上面的示例还定义了一个名为 VideoMode
的类,用来描述视频显示器的某个特定视频模式。这个类包含了四个可变的存储属性。第一个, resolution
,被初始化为一个新的 Resolution
结构体的实例,属性类型被推断为 Resolution
。新 VideoMode
实例同时还会初始化其它三个属性,它们分别是初始值为 false
的 interlaced
(意为“非隔行视频”),初始值为 0.0
的 frameRate
,以及值为可选 String
的 name
。因为 name
是一个可选类型,它会被自动赋予一个默认值 nil
,意为“没有 name
值”。
结构体和类的实例
Resolution
结构体和 VideoMode
类的定义仅描述了什么是 Resolution
和 VideoMode
。它们并没有描述一个特定的分辨率(resolution)或者视频模式(video mode)。为此,你需要创建结构体或者类的一个实例。
创建结构体和类实例的语法非常相似:
let someResolution = Resolution()
let someVideoMode = VideoMode()
结构体和类都使用构造器语法来创建新的实例。构造器语法的最简单形式是在结构体或者类的类型名称后跟随一对空括号,如 Resolution()
或 VideoMode()
。通过这种方式所创建的类或者结构体实例,其属性均会被初始化为默认值。构造过程 章节会对类和结构体的初始化进行更详细的讨论。