概念 #
在 Swift 中,结构体 struct
是一种非常有用的数据类型。它允许你将一组相关的值组合在一起,并定义它们的行为。结构体在 Swift 中是值类型,与类 class
的引用类型有显著的区别。
结构体的定义 #
定义一个结构体使用 struct
关键字,结构体中可以包含属性(存储属性和计算属性)和方法。
struct Resolution {
var width: Int
var height: Int
}
在这个例子中,Resolution
结构体包含了两个存储属性 width
和 height
。
创建结构体实例 #
你可以通过成员初始化器来创建结构体实例:
let res = Resolution(width: 1920, height: 1080)
在这个例子中,res
是一个新的 Resolution
实例,其 width
属性为 1920,height
属性为 1080。
访问和修改属性 #
可以通过点语法来访问和修改结构体的属性:
print("The resolution width is \(res.width)")
// 如果需要修改,需要将实例声明为 var
var modifiableRes = res
modifiableRes.width = 1280
print("The new resolution width is \(modifiableRes.width)")
方法 #
结构体可以包含方法,这些方法可以使用和修改结构体的属性。
struct Resolution {
var width: Int
var height: Int
func display() {
print("Resolution: \(width)x\(height)")
}
mutating func resize(toWidth width: Int, andHeight height: Int) {
self.width = width
self.height = height
}
}
var res = Resolution(width: 1920, height: 1080)
res.display() // 输出: Resolution: 1920x1080
res.resize(toWidth: 1280, andHeight: 720)
res.display() // 输出: Resolution: 1280x720
在这个例子中,display()
方法用来打印分辨率,而 resize(toWidth:andHeight:)
方法是一个 mutating
方法,它可以修改结构体的属性。
构造器 #
当你定义一个结构体时,Swift 会自动提供一个成员初始化方法,你也可以自定义构造器:
struct Resolution {
var width: Int
var height: Int
init(width: Int, height: Int) {
self.width = width
self.height = height
}
}
值类型 #
结构体是值类型,这意味着结构体的实例在赋值和传递过程中会被拷贝:
let res1 = Resolution(width: 1920, height: 1080)
var res2 = res1
res2.width = 1280
print("res1 width: \(res1.width)") // 输出: res1 width: 1920
print("res2 width: \(res2.width)") // 输出: res2 width: 1280
在这个例子中,res1
和 res2
是两个独立的实例,对 res2
的修改不会影响 res1
。
结构体与类的对比 #
结构体的特点:
- 值类型:结构体在赋值和传递时总是被拷贝。
- 不需要继承:结构体不支持继承。
- 自动成员初始化器:Swift 自动为结构体提供成员初始化器。
- 更适合表示简单的数据:例如几何图形、坐标、范围等。
类的特点:
- 引用类型:类在赋值和传递时总是引用同一个实例。
- 支持继承:类可以继承自其他类,并且可以使用多态。
- 需要手动定义初始化方法:类通常需要显式定义初始化方法。
- 更适合表示需要共享状态的数据:例如用户对象、单例模式等。
小结 #
结构体在 Swift 中是一种灵活强大的值类型,适用于表示简单的数据结构。它们使用方便,适合那些不需要继承和共享状态的情况。
- 定义结构体 通过
struct
关键字。 - 存储属性和计算属性:可以包含存储真实数据的属性,也可以包含计算属性。
- 方法:可以包含操作和修改结构体属性的方法。
- 值类型 赋值和传递时会被拷贝。
- 构造器 可以使用默认的成员初始化方法或自定义构造方法。
理解结构体和类之间的区别以及何时使用它们,对于开发高效、健壮的 Swift 应用至关重要。
使用实例 #
1. 定义一个简单的结构体 #
struct Rectangle {
var width: Int
var height: Int
var area: Int {
width * height
}
mutating func scale(by factor: Int) {
width *= factor
height *= factor
}
}
var rect = Rectangle(width: 10, height: 5)
print(rect.area) // 输出:50
rect.scale(by: 2)
print(rect.area) // 输出:200
2. 属性观察器 #
struct Account {
var balance: Int {
willSet {
print("About to set balance to \(newValue)")
}
didSet {
print("Balance changed from \(oldValue) to \(balance)")
}
}
}
var account = Account(balance: 1000)
account.balance = 1200 // 触发 willSet 和 didSet
3. 嵌套 Struct #
struct Computer {
struct Processor {
var cores: Int
var frequency: Double
}
var processor: Processor
}
let myComputer = Computer(processor: Computer.Processor(cores: 8, frequency: 3.5))
print("Processor cores: \(myComputer.processor.cores)")
4. 静态属性与方法 #
struct Student {
static var totalStudents = 0
var name: String
init(name: String) {
self.name = name
Student.totalStudents += 1
}
static func printTotalStudents() {
print("Total students: \(totalStudents)")
}
}
let student1 = Student(name: "Alice")
let student2 = Student(name: "Bob")
Student.printTotalStudents() // 输出:Total students: 2
5. 可失败构造器 #
struct Person {
var name: String
var age: Int
init?(name: String, age: Int) {
if age < 0 {
return nil // 返回 nil 表示构造失败
}
self.name = name
self.age = age
}
}
if let person = Person(name: "Alice", age: -1) {
print("\(person.name) was created")
} else {
print("Invalid age")
}
注意事项 #
值类型行为:
- 结构体是值类型,当赋值或传递时,其实例会被复制。相较于类,它不会共享同一对象的引用。
var rect1 = Rectangle(width: 10, height: 20) var rect2 = rect1 rect2.width = 30 print(rect1.width) // 输出:10(rect1 未受 rect2 修改影响)
静态成员:
- 静态(
static
)属性或方法对所有实例共享。 - 对于只需存储在类型本身的数据,可以用静态属性。
- 静态(
用作轻量建模:
- 结构体最常用于封装轻量数据。对于复杂的行为或需要继承的场景,推荐使用类。
不可变结构体:
- 如果结构体用
let
声明为常量,就无法修改它的属性,即使属性本身是var
类型。
- 如果结构体用
总结 #
常用特性: #
属性:
- 存储属性:
var
和let
- 计算属性:
var
- 属性观察器:
willSet
和didSet
- 存储属性:
方法:
- 实例方法
- 修改方法(需要
mutating
修饰) - 静态方法
初始化:
- 默认初始化、自定义初始化、可失败初始化
适用场景: #
- 封装一组轻量且相关的数据。
- 创建不可变的数据结构。
- 需要避免复杂引用和共享状态的场景。