struct — 是什么、关键概念以及 Swift 语法

作者: IT Sectr 发布日期: 2026-06-17 阅读时间: 7 分钟

struct 是 Swift 语言中的一种值类型(value type),其实例在代码片段之间传递时会被复制。与类不同,结构体不支持继承,但可以实现协议、包含属性和方法,并在没有 ARC 的情况下提供可预测的内存管理。根据 Swift 编程语言指南 2026struct 是 Swift 的基本构建块——甚至标准类型 Int、String、Array 和 Dictionary 也是作为结构体实现的。该语言推荐结构体作为数据建模的首选。

要点

  • Struct — Swift 中的值类型,赋值时被复制,按值而不是按引用传递。
  • Copy-on-Write — 一种优化,实际数据复制仅在值更改时进行,而不是在赋值时。
  • Mutating — 修改结构体属性的方法所需的关键字。
  • 协议 — 结构体可以实现协议和扩展,无需继承即可提供灵活性。
  • 安全性 — 没有引用循环使得结构体更适合多线程代码和数据模型。

Swift 中的 struct 是什么?

Struct(结构体)是 Swift 中的一种复合数据类型,它将相关的属性和方法分组到一个实体中。与类不同,结构体是值类型(value types):当传递给函数或赋值给新变量时,会创建结构体的独立副本,而不是对原始对象的引用。

Swift 对所有原始类型使用结构体:Int、Double、String、Bool、Array、Dictionary 和 Set。这意味着即使是基本的 Int 数字也像结构体一样行为——赋值时会创建副本。开发人员可以定义自己的结构体,具有任意属性和方法集合。

根据 Swift Evolution (SE-0143),将标准类型实现为结构体的决定是出于性能和可预测性的考虑。值类型不会创建引用循环,不需要 ARC 引用计数,并保证副本的更改不会影响原始数据——这对于多线程场景中的数据不可变性至关重要。

Struct 作为值类型

值类型语义(Value type semantics)—— struct 和 class 之间的关键区别。当您将结构体赋值给新变量或传递给函数时,Swift 会创建所有数据的独立副本。副本中的任何更改都不会影响原始数据,从而消除了引用类型特有的副作用。

swift
// 值类型语义示例
struct Point {
    var x: Double
    var y: Double
}

var p1 = Point(x: 10, y: 20)
var p2 = p1        // p2 是 p1 的独立副本
p2.x = 99            // 只有 p2 改变
print(p1.x)         // 10 — p1 不变
print(p2.x)         // 99

Copy-on-Write 优化

Swift 使用 Copy-on-Write(COW)来优化复制。如果多个变量引用同一个结构体,但没有一个修改数据,则不会发生实际复制。Swift 在变量之间共享内存,直到第一次修改——然后创建真正的副本。这可以防止不必要的分配操作并加快与集合的工作速度。

可变性与 mutating 方法

默认情况下,结构体的方法不能修改其属性——Swift 要求对进行更改的方法显式指定 mutating。此限制可防止意外修改并使代码可预测:如果方法未标记为 mutating,则保证不会修改结构体。

Mutating 实际应用

当您在方法前添加 mutating 关键字时,Swift 可以编写新值到结构体的属性中。实际上,该方法甚至可以通过 self = 完全替换结构体实例为新实例。此机制用于例如 Option 和 Result 类型。

swift
// 带有 mutating 方法的结构体
struct Counter {
    private var value: Int = 0

    // Mutating 方法——可以修改属性
    mutating func increment() {
        value += 1
    }

    // Mutating 方法可以完全替换 self
    mutating func reset() {
        self = Counter()
    }

    // Non-mutating 方法——只读
    func currentValue() -> Int {
        return value
    }
}

var counter = Counter()
counter.increment()
print(counter.currentValue())  // 1
counter.reset()
print(counter.currentValue())  // 0

Mutating 规则:结构体必须通过 var 声明,而不是 let —— 常量结构体不能调用 mutating 方法。编译器在构建阶段检查这一点:尝试在 let 常量上调用 mutating 方法会导致编译错误。

Struct vs Class:比较

在 struct 和 class 之间选择是 Swift 中的基本决策之一。两种类型都可以包含属性、方法、初始化器并实现协议,但在内存语义、继承和生命周期管理方面存在根本差异。

特性structclass
类型值类型(被复制)引用类型(引用)
继承不支持支持
ARC / 引用计数不需要需要 ARC
反初始化不支持支持 deinit
常量中修改属性仅通过 var可以通过 let(引用是常量)
类型转换不支持支持
在集合中存储直接存储(值)作为引用存储(指针)

当数据不需要继承、不应具有共享标识(例如坐标、尺寸、配置)并在模块之间传递时,首选结构体。类用于 UI 组件(UIView、UIViewController)、单例和具有共享标识的对象。

何时选择 struct

Apple 建议在 Swift 中使用 struct 作为数据建模的默认类型。由于可预测的复制语义和没有引用计数的开销,结构体适用于大多数场景。让我们看看结构体是最佳选择的典型情况。

无需继承的数据模型

如果实体包含数据而不需要继承(Product、User、Order、Point),请使用 struct。编译器会自动生成 memberwise 初始化器——您无需手动编写 init。Equatable 和 Hashable 也自动为所有属性满足这些协议的结构体实现。

不可变(immutable)数据

对于创建后不更改的配置、设置和标志,struct 比 class 更可取。常量(let)结构体保证所有嵌套字段的不可变性——在 class 中,这仅适用于引用,而不适用于对象的内容。

多线程代码

由于值类型语义,结构体在多线程环境中是安全的。每个线程获得独立的数据副本,不会影响其他线程。值类型之间不可能出现竞态条件,这使得结构体成为 SwiftUI 中模型的首选(ObservableObject 需要 class,但 @State 使用 struct)。

swift
// 结构体用于数据模型的示例
struct User: Codable, Identifiable {
    let id: UUID
    var name: String
    var email: String
    var isPremium: Bool

    // 计算属性——non-mutating
    var displayName: String {
        isPremium ? "\(name) ⭐️" : name
    }
}

// 自动 memberwise 初始化器
let user = User(
    id: UUID(),
    name: "Alice",
    email: "alice@example.com",
    isPremium: true
)

// 复制对多线程安全
var userCopy = user
userCopy.isPremium = false
// user.isPremium 保持为 true

当您需要继承(UIKit/AppKit 组件)、共享标识(delegate、observer)或受控对象生命周期(deinit)时,请使用 class。其他所有情况——struct。

常见问题

Swift 中的 struct 是什么?

Struct 在 Swift 中是一种值类型(value type),在代码片段之间传递时被复制。结构体可以包含属性、方法、初始化器并实现协议。Swift 的基本类型(Int、String、Array)都是作为结构体实现的。

Swift 中 struct 和 class 有什么区别?

Struct — 值类型(赋值时被复制),不支持继承,不需要 ARC。Class — 引用类型(通过引用传递),支持继承、反初始化和引用计数。开发人员推荐 struct 作为默认类型。

Swift 中 struct 的 mutating 是什么?

Mutating — 指示结构体方法可以修改其属性的关键字。没有 mutating,编译器禁止修改字段。Mutating 方法只能在通过 var 声明的变量上调用,而不是 let。

Swift 中的 Copy-on-Write 是什么?

Copy-on-Write(COW)—— Swift 对结构体的优化,实际数据复制被延迟到第一次修改的时刻。只要所有变量只读取结构体,它们共享一个内存区域。这提高了处理大型集合时的性能。

在 Swift 中什么时候使用 struct,什么时候使用 class?

对无需继承的数据模型、配置、DTO 和多线程场景使用 struct。对 UIKit/AppKit UI 组件、单例、具有共享标识的实体(delegate、observer)和需要反初始化的对象使用 class

总结

  • Struct 是 Swift 中的值类型(value type),赋值时被复制,在副本之间提供可预测的行为,没有副作用。
  • Copy-on-Write 优化结构体的性能——实际复制仅在第一次修改时发生,而不是每次赋值。
  • Swift 标准类型——Int、String、Array、Dictionary——作为结构体实现,保证所有基本操作的值类型语义。
  • Mutating——修改结构体属性的方法的必需关键字;只能在 var 实例上调用。
  • 结构体不支持继承,但实现协议并可以使用扩展来添加功能。
  • Equatable 和 Hashable 自动为所有属性满足这些协议的结构体实现——简化了比较和在集合中的使用。
  • Apple 推荐 struct 作为默认类型——仅当需要继承、共享标识或受控对象生命周期时才使用 class。

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读