乐闻世界logo
搜索文章和话题

Swift 中的结构体和类有什么区别?何时选择结构体?

2月21日 15:05

Swift 中的结构体和类有什么区别?在什么情况下应该选择结构体而不是类?

Swift 中的结构体和类都是用于定义自定义数据类型的构造,但它们在内存管理、赋值行为和使用场景上有重要区别。

主要区别:

  1. 值类型 vs 引用类型:

    • 结构体是值类型,赋值时创建副本
    • 类是引用类型,赋值时传递引用
    • 示例:
      swift
      struct Point { var x: Int var y: Int } class Circle { var center: Point var radius: Int init(center: Point, radius: Int) { self.center = center self.radius = radius } } var point1 = Point(x: 0, y: 0) var point2 = point1 point2.x = 10 print(point1.x) // 0 (point1 不受影响) var circle1 = Circle(center: Point(x: 0, y: 0), radius: 5) var circle2 = circle1 circle2.radius = 10 print(circle1.radius) // 10 (circle1 受影响)
  2. 继承:

    • 类支持继承,可以继承其他类的属性和方法
    • 结构体不支持继承
    • 示例:
      swift
      class Vehicle { var speed: Int = 0 func accelerate() { speed += 10 } } class Car: Vehicle { var brand: String init(brand: String) { self.brand = brand } }
  3. 类型转换:

    • 类支持类型检查和转换(is、as)
    • 结构体不支持类型转换
    • 示例:
      swift
      let vehicle: Vehicle = Car(brand: "Toyota") if let car = vehicle as? Car { print(car.brand) }
  4. 引用计数:

    • 类使用 ARC(自动引用计数)管理内存
    • 结构体不需要引用计数,直接在栈上分配
    • 类可能导致循环引用,需要使用 weak 或 unowned
  5. 析构器:

    • 类可以定义析构器(deinit)
    • 结构体不能定义析构器
    • 示例:
      swift
      class FileHandler { let fileHandle: FileHandle init(path: String) { self.fileHandle = FileHandle(forReadingAtPath: path)! } deinit { fileHandle.closeFile() } }

选择结构体的场景:

  1. 数据模型主要是值类型
  2. 数据需要独立存在,不希望被意外修改
  3. 数据相对较小,复制成本较低
  4. 不需要继承
  5. 需要线程安全的操作
  6. 需要比较值相等性

选择类的场景:

  1. 需要继承和多态
  2. 需要共享状态
  3. 数据较大,复制成本高
  4. 需要控制生命周期和内存管理
  5. 需要使用标识符比较
  6. 需要使用析构器

最佳实践:

  1. 优先使用结构体,只有在需要引用类型特性时才使用类
  2. 使用结构体表示简单的数据模型
  3. 使用类表示具有身份和行为对象
  4. 在需要继承时使用类
  5. 注意类可能导致的循环引用问题
标签:Swift