结构体 #

一、结构体概述 #

结构体是一种值类型,用于封装相关数据和功能。

1.1 结构体特点 #

  • 值类型
  • 复制时创建副本
  • 自动生成初始化器
  • 适合数据模型

二、定义结构体 #

2.1 基本语法 #

swift
struct Person {
    var name: String
    var age: Int
    
    func introduce() -> String {
        return "我是\(name),今年\(age)岁"
    }
}

let person = Person(name: "张三", age: 25)
print(person.introduce())

2.2 存储属性 #

swift
struct Rectangle {
    var width: Double
    var height: Double
    let id: Int
}

var rect = Rectangle(width: 10, height: 5, id: 1)
rect.width = 20
print(rect.width)

2.3 计算属性 #

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

var circle = Circle(radius: 5)
print(circle.area)
circle.diameter = 20
print(circle.radius)

三、初始化器 #

3.1 自动初始化器 #

swift
struct Point {
    var x: Double
    var y: Double
}

let point1 = Point(x: 10, y: 20)
let point2 = Point(x: 0, y: 0)

3.2 自定义初始化器 #

swift
struct Size {
    var width: Double
    var height: Double
    
    init(width: Double, height: Double) {
        self.width = width
        self.height = height
    }
    
    init(square side: Double) {
        self.width = side
        self.height = side
    }
    
    init() {
        self.width = 0
        self.height = 0
    }
}

let size1 = Size(width: 10, height: 20)
let size2 = Size(square: 5)
let size3 = Size()

3.3 可失败初始化器 #

swift
struct Person {
    var name: String
    var age: Int
    
    init?(name: String, age: Int) {
        guard age >= 0 else { return nil }
        self.name = name
        self.age = age
    }
}

if let person = Person(name: "张三", age: -1) {
    print(person.name)
} else {
    print("初始化失败")
}

四、方法 #

4.1 实例方法 #

swift
struct Counter {
    var count: Int = 0
    
    func current() -> Int {
        return count
    }
    
    mutating func increment() {
        count += 1
    }
    
    mutating func reset() {
        count = 0
    }
}

var counter = Counter()
counter.increment()
print(counter.current())

4.2 mutating方法 #

swift
struct Point {
    var x: Double
    var y: Double
    
    mutating func moveBy(x deltaX: Double, y deltaY: Double) {
        x += deltaX
        y += deltaY
    }
    
    mutating func moveTo(x: Double, y: Double) {
        self = Point(x: x, y: y)
    }
}

var point = Point(x: 0, y: 0)
point.moveBy(x: 10, y: 20)
print("(\(point.x), \(point.y))")

4.3 类型方法 #

swift
struct MathUtility {
    static let pi = 3.14159
    
    static func square(_ x: Double) -> Double {
        return x * x
    }
    
    static func cube(_ x: Double) -> Double {
        return x * x * x
    }
}

print(MathUtility.pi)
print(MathUtility.square(5))

五、值类型语义 #

5.1 复制语义 #

swift
struct Point {
    var x: Double
    var y: Double
}

var point1 = Point(x: 10, y: 20)
var point2 = point1

point2.x = 100

print(point1.x)
print(point2.x)

5.2 函数参数 #

swift
struct Point {
    var x: Double
    var y: Double
}

func modifyPoint(_ point: Point) -> Point {
    var newPoint = point
    newPoint.x += 10
    return newPoint
}

var point = Point(x: 0, y: 0)
let newPoint = modifyPoint(point)
print(point.x)
print(newPoint.x)

5.3 inout参数 #

swift
struct Point {
    var x: Double
    var y: Double
}

func movePoint(_ point: inout Point, by deltaX: Double, and deltaY: Double) {
    point.x += deltaX
    point.y += deltaY
}

var point = Point(x: 0, y: 0)
movePoint(&point, by: 10, and: 20)
print("(\(point.x), \(point.y))")

六、结构体与类 #

6.1 选择建议 #

使用结构体当:

  • 主要目的是封装数据
  • 需要值语义
  • 不需要继承
  • 数据简单

使用类当:

  • 需要引用语义
  • 需要继承
  • 需要共享状态
  • 需要析构器

6.2 对比示例 #

swift
struct PointStruct {
    var x: Double
    var y: Double
}

class PointClass {
    var x: Double
    var y: Double
    
    init(x: Double, y: Double) {
        self.x = x
        self.y = y
    }
}

var struct1 = PointStruct(x: 1, y: 2)
var struct2 = struct1
struct2.x = 10
print(struct1.x)

var class1 = PointClass(x: 1, y: 2)
var class2 = class1
class2.x = 10
print(class1.x)

七、实际应用 #

7.1 数据模型 #

swift
struct User {
    let id: Int
    var name: String
    var email: String
    var age: Int
    
    var isAdult: Bool {
        return age >= 18
    }
    
    func formatted() -> String {
        return "\(name) (\(email))"
    }
}

var user = User(id: 1, name: "张三", email: "zhangsan@example.com", age: 25)
print(user.formatted())
print(user.isAdult)

7.2 几何图形 #

swift
struct Rectangle {
    var origin: Point
    var size: Size
    
    var area: Double {
        return size.width * size.height
    }
    
    var center: Point {
        return Point(
            x: origin.x + size.width / 2,
            y: origin.y + size.height / 2
        )
    }
    
    func contains(_ point: Point) -> Bool {
        return point.x >= origin.x &&
               point.x <= origin.x + size.width &&
               point.y >= origin.y &&
               point.y <= origin.y + size.height
    }
}

7.3 配置选项 #

swift
struct NetworkConfig {
    var baseURL: String
    var timeout: TimeInterval
    var retryCount: Int
    var headers: [String: String]
    
    static let `default` = NetworkConfig(
        baseURL: "https://api.example.com",
        timeout: 30,
        retryCount: 3,
        headers: ["Content-Type": "application/json"]
    )
}

let config = NetworkConfig.default
print(config.baseURL)

八、协议遵循 #

8.1 Equatable #

swift
struct Point: Equatable {
    var x: Double
    var y: Double
    
    static func == (lhs: Point, rhs: Point) -> Bool {
        return lhs.x == rhs.x && lhs.y == rhs.y
    }
}

let p1 = Point(x: 1, y: 2)
let p2 = Point(x: 1, y: 2)
print(p1 == p2)

8.2 Codable #

swift
struct User: Codable {
    let id: Int
    var name: String
    var email: String
}

let user = User(id: 1, name: "张三", email: "test@example.com")

let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted

if let data = try? encoder.encode(user),
   let json = String(data: data, encoding: .utf8) {
    print(json)
}

九、总结 #

本章学习了Swift结构体:

  • 定义:属性和方法
  • 初始化器:自动和自定义
  • mutating:修改自身
  • 值类型:复制语义

最佳实践:

  • 优先使用结构体
  • 使用值类型保证安全
  • 遵循协议增加功能
  • 合理使用mutating

下一章,我们将学习泛型!

最后更新:2026-03-26