Swift 结构体:struct 与类的区别
在 Swift 中,struct(结构体)和 class(类)都能用来定义自定义数据类型,但它们在内存管理、行为特性上存在根本差异。选择 struct 还是 class,直接影响程序的性能、安全性和可维护性。本文通过具体场景和代码对比,帮你快速掌握两者的核心区别。
1. 值类型 vs 引用类型
理解值类型和引用类型是区分 struct 和 class 的关键。
- struct 是值类型:当你把一个 struct 赋值给新变量,或作为参数传递时,Swift 会复制整个数据。
- class 是引用类型:赋值或传参时,Swift 只复制指向对象的引用(即“指针”),多个变量共享同一个实例。
验证值类型行为:
struct Point {
var x: Int
var y: Int
}
var a = Point(x: 1, y: 2)
var b = a // 复制 a 的值
b.x = 10 // 修改 b 不影响 a
print(a.x) // 输出 1
print(b.x) // 输出 10
验证引用类型行为:
class Person {
var name: String
init(name: String) { self.name = name }
}
let p1 = Person(name: "Alice")
let p2 = p1 // p2 和 p1 指向同一个对象
p2.name = "Bob"
print(p1.name) // 输出 Bob(因为 p1 和 p2 共享同一实例)
print(p2.name) // 输出 Bob
2. 初始化与构造器
struct 自动获得成员逐一构造器,class 则没有。
当你定义一个 struct 时,Swift 会自动为你生成一个初始化方法,参数顺序与属性声明一致:
struct Rectangle {
var width: Double
var height: Double
}
// 自动获得 init(width:height:)
let rect = Rectangle(width: 5.0, height: 3.0)
而 class 不会自动生成这种构造器,你必须手动实现:
class Circle {
var radius: Double
// 必须显式定义构造器
init(radius: Double) {
self.radius = radius
}
}
let circle = Circle(radius: 4.0)
注意:如果 struct 的所有属性都有默认值,则可以不写任何构造器,直接使用
StructName()初始化。
3. 继承能力
class 支持继承,struct 不支持。
你可以让一个 class 继承另一个 class,获得其属性和方法,并可重写(override)行为:
class Vehicle {
var speed: Double = 0.0
func move() { print("Moving") }
}
class Car: Vehicle {
override func move() {
print("Car is moving at \(speed) km/h")
}
}
而 struct 不能继承其他 struct 或 class。这是 struct 的硬性限制。
4. 可变性(Mutating)
在 struct 中修改自身属性需要标记为 mutating,class 则不需要。
因为 struct 是值类型,默认情况下其方法不能修改自身的属性(保证不可变性)。若要修改,必须显式声明:
struct Counter {
var count = 0
mutating func increment() {
count += 1 // 合法:因为方法是 mutating
}
}
var c = Counter()
c.increment() // OK
而在 class 中,方法可以直接修改属性:
class CounterClass {
var count = 0
func increment() {
count += 1 // 无需 mutating
}
}
如果你尝试在非
mutating方法中修改 struct 属性,编译器会报错。
5. 内存管理和性能
struct 存储在栈上(stack),class 实例存储在堆上(heap)。
- 栈内存分配快、释放快,适合小型、频繁创建销毁的数据(如坐标点、尺寸、颜色)。
- 堆内存需要引用计数管理(ARC),有额外开销,适合大型、长期存在的对象(如用户、网络请求)。
因此,优先使用 struct 可提升性能并避免循环引用问题。
何时使用 struct?何时使用 class?
下表总结了选择依据:
| 场景 | 推荐类型 | 理由 |
|---|---|---|
| 数据只是简单值(如 Point、Size、RGBColor) | struct |
值语义更安全,无共享副作用 |
| 需要继承或运行时多态 | class |
struct 不支持继承 |
| 对象需要被多个地方共享并同步状态 | class |
引用语义天然支持共享 |
| 性能敏感的小型数据结构 | struct |
栈分配更快,无 ARC 开销 |
需要遵守 NSObject 或 Cocoa 框架协议 |
class |
许多 UIKit/AppKit API 要求 class |
通用原则:除非你需要 class 的特性(如继承、引用语义),否则优先使用 struct。Apple 官方也建议:“Use structs for things that are values.”
验证你的选择是否合理
检查以下问题:
- 这个类型是否代表一个“值”?(比如
(x: 10, y: 20)就是一个位置值) - 多个变量是否应该拥有独立副本?(修改一个不应影响另一个)
- 是否不需要继承?
如果三个问题答案都是“是”,就用 struct。
反例:如果你发现 struct 中包含大量属性,且经常需要通过引用来共享状态,那它可能更适合改为 class。
// ✅ 合理使用 struct:表示几何矩形
struct Rect {
var origin: Point
var size: Size
}
// ❌ 不合理:试图用 struct 模拟 UI 控件(应使用 class)
struct Button { // 错误:UI 控件需引用语义和继承
var title: String
var action: () -> Void
}
记住:struct 更适合“数据”,class 更适合“对象”。

暂无评论,快来抢沙发吧!