Swift 结构体:从入门到实战
2026/9/7 2:46:05 网站建设 项目流程

1. 引言

在 Swift 中,结构体(Struct)是构建数据模型和高性能代码的核心工具。与类不同,结构体是值类型,这意味着它在赋值和传递时会被复制,从而避免共享状态带来的复杂性。本文将带你深入理解 Swift 结构体的定义、初始化、属性、方法、扩展及其与类的对比,并通过丰富的代码实例帮助你快速掌握。

2. 结构体的基本定义

使用struct关键字即可定义一个结构体,内部可以声明存储属性:

struct Point { var x: Double var y: Double } let origin = Point(x: 0, y: 0) print(origin.x) // 0.0

结构体会自动获得一个“成员逐一初始化器”(Memberwise Initializer),可以按属性名传入初始值。

3. 初始化方法

虽然默认的成员初始化器很方便,但很多时候我们需要自定义初始化逻辑。

struct Rectangle { var width: Double var height: Double // 自定义初始化器 init(squareSide side: Double) { width = side height = side } } let square = Rectangle(squareSide: 10) // square.width 和 square.height 都是 10

还可以添加可失败初始化器或带默认值的属性:

struct Car { var brand: String var year: Int init?(brand: String, year: Int) { guard !brand.isEmpty, year > 1885 else { return nil } self.brand = brand self.year = year } }

4. 结构体是值类型

结构体赋值或传递给函数时,会进行深拷贝。修改一个变量不会影响另一个:

struct Point { var x = 0, y = 0 } var p1 = Point(x: 1, y: 2) var p2 = p1 // 拷贝 p2.x = 10 print(p1.x) // 1 print(p2.x) // 10

而类是引用类型,共享同一实例。这是结构体和类最本质的区别,也是 Swift 推荐优先使用结构体的原因之一。

5. 属性和方法

5.1 存储属性与计算属性

结构体可以拥有存储属性和计算属性,计算属性不直接存储值,而是通过 get/set 提供:

struct Circle { var radius: Double var diameter: Double { get { return radius * 2 } set { radius = newValue / 2 } } }

5.2 属性观察器

可以为存储属性添加willSetdidSet

struct StepCounter { var totalSteps: Int = 0 { willSet { print("将步数设置为 \(newValue)") } didSet { if totalSteps > oldValue { print("增加了 \(totalSteps - oldValue) 步") } } } }

5.3 方法

结构体内部可以定义实例方法和类型方法:

struct Vector2D { var x = 0.0, y = 0.0 func length() -> Double { return sqrt(x * x + y * y) } static func unitX() -> Vector2D { return Vector2D(x: 1, y: 0) } }

5.4 mutating 方法

默认情况下,结构体实例方法不能修改实例的属性。如果需要修改,必须在方法前添加mutating关键字:

struct Point { var x = 0.0, y = 0.0 mutating func moveBy(dx: Double, dy: Double) { x += dx y += dy } } var point = Point(x: 1, y: 1) point.moveBy(dx: 2, dy: 3) // 现在 point 的坐标为 (3, 4)

6. 下标

结构体可以定义下标(subscript),方便通过索引访问内部数据:

struct TimesTable { let multiplier: Int subscript(index: Int) -> Int { return multiplier * index } } let threeTimesTable = TimesTable(multiplier: 3) print(threeTimesTable[6]) // 18

7. 嵌套类型

结构体内部可以嵌套枚举、结构体或类,形成更清晰的层级结构:

struct ChessBoard { enum Piece { case king, queen, rook, bishop, knight, pawn } struct Square { var row: Int var column: Int var piece: Piece? } var squares: [[Square]] = [] }

8. 结构体的扩展

通过扩展(Extension),可以为已有结构体添加新功能,甚至可以扩展 Swift 标准库中的结构体:

extension Point { // 添加计算属性 var isOrigin: Bool { return x == 0 && y == 0 } // 添加方法 func distance(to other: Point) -> Double { let dx = x - other.x let dy = y - other.y return sqrt(dx * dx + dy * dy) } }

9. 遵循协议

结构体可以遵循一个或多个协议,例如EquatableHashableCodable,从而获得相等性比较、哈希、编解码等能力:

struct Person: Codable, Equatable { var name: String var age: Int } let alice = Person(name: "Alice", age: 30) let encoder = JSONEncoder() let data = try encoder.encode(alice)

10. 结构体与类的对比总结

特性结构体
类型值类型引用类型
继承不支持支持
类型转换不支持支持is/as?
析构函数deinit
引用计数有 ARC
可变性实例常量不可变,方法需mutating实例常量可修改属性
使用建议优先用于数据模型、数值类型等需要继承或共享状态时使用

11. 实战示例:构建用户信息模型

下面演示如何用结构体构建一个用户管理系统的数据模型,并结合计算属性和 Codable 协议进行数据持久化:

struct Address: Codable { var street: String var city: String var zipCode: String } struct User: Codable, Equatable { var id: Int var name: String var email: String var address: Address var displayName: String { return "\(name) (#\(id))" } static func loadFromDisk() throws -> [User] { let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] .appendingPathComponent("users.json") let data = try Data(contentsOf: url) return try JSONDecoder().decode([User].self, from: data) } }

这个模型可以直接用于 JSON 解析和本地存储,充分体现了结构体在 Swift 开发中的便利性。

12. 结语

Swift 结构体是构建安全、高效代码的基石。理解其值语义、初始化器、属性和方法、扩展以及与协议的配合,能帮助你写出更健壮的 iOS 或服务端 Swift 程序。希望本文的代码实例能为你提供实用的参考。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询