在 Swift 中,struct
(结构体)和 class
(类)是两种重要的数据类型,它们有一些相似的地方,但也有许多关键的区别。以下是它们的主要区别:
1. 值类型 vs 引用类型
-
结构体(struct):是值类型。当你创建一个结构体的实例并将其赋值给一个变量或常量,或者将其传递给一个函数时,实际上是创建了这个结构体的一个副本。每个副本都是独立的,修改一个副本不会影响其他副本。
struct Point { var x: Int var y: Int } var point1 = Point(x: 0, y: 0) var point2 = point1 point2.x = 10 print(point1.x) // 输出 0 print(point2.x) // 输出 10
-
类(class):是引用类型。当你创建一个类的实例并将其赋值给一个变量或常量,或者将其传递给一个函数时,实际上是传递了这个类的引用。多个变量或常量可以引用同一个类实例,修改一个引用会影响所有引用。
class Point { var x: Int var y: Int init(x: Int, y: Int) { self.x = x self.y = y } } var point1 = Point(x: 0, y: 0) var point2 = point1 point2.x = 10 print(point1.x) // 输出 10 print(point2.x) // 输出 10
2. 继承
-
结构体(struct):不支持继承。你不能从一个结构体继承另一个结构体。
struct A { var value: Int } // struct B: A { // 错误,结构体不支持继承 // }
-
类(class):支持继承。你可以从一个类继承另一个类,并且可以重写父类的方法和属性。
class Animal { func makeSound() { print("Some generic animal sound") } } class Dog: Animal { override func makeSound() { print("Bark") } } let myDog = Dog() myDog.makeSound() // 输出 "Bark"
3. 构造器
-
结构体(struct):自动生成成员逐一构造器,你可以直接使用它来初始化结构体的实例。
struct Point { var x: Int var y: Int } let point = Point(x: 10, y: 20)
-
类(class):不会自动生成成员逐一构造器,你需要自己定义构造器。
class Point { var x: Int var y: Int init(x: Int, y: Int) { self.x = x self.y = y } } let point = Point(x: 10, y: 20)
4. 引用计数和内存管理
-
结构体(struct):由于是值类型,结构体不涉及引用计数和垃圾回收。
-
类(class):作为引用类型,类实例由引用计数管理。Swift 使用自动引用计数(ARC)来管理类实例的内存。
5. 可变性
-
结构体(struct):如果你定义了一个结构体实例为常量(
let
),那么它的所有属性也都是不可变的,即使这些属性是变量(var
)。struct Point { var x: Int var y: Int } let point = Point(x: 10, y: 20) // point.x = 30 // 错误,point 是常量
-
类(class):如果你定义了一个类实例为常量(
let
),你仍然可以修改它的可变属性(var
)。class Point { var x: Int var y: Int init(x: Int, y: Int) { self.x = x self.y = y } } let point = Point(x: 10, y: 20) point.x = 30 // 正确,尽管 point 是常量
6. 协议一致性
-
结构体(struct):可以通过扩展(
extension
)来遵循协议,并且可以在扩展中添加默认实现。 -
类(class):同样可以通过扩展来遵循协议,并且可以在扩展中添加默认实现。
总结来说,选择使用 struct
还是 class
取决于你的需求。如果你需要值语义(每次赋值或传递时创建副本)和简单的数据封装,使用 struct
。如果你需要引用语义(多个引用指向同一个实例)、继承和更复杂的对象行为,使用 class
。