Swift 构造过程详解:从基础到进阶的完整指南

发布时间:2026/7/19 14:10:37
Swift 构造过程详解:从基础到进阶的完整指南 1. 引言什么是构造过程在 Swift 中构造过程是使用类、结构体或枚举实例之前的准备过程。这个过程涉及为实例中的每个存储属性设置初始值并执行任何其他必要的设置或初始化。与 Objective-C 不同Swift 的构造过程没有返回值其主要作用是确保新实例在第一次使用前被正确初始化。本文将深入探讨 Swift 构造过程的各个方面包括存储属性的初始赋值自定义构造器默认构造器与逐一成员构造器值类型与引用类型的构造器代理可失败构造器与必要构造器通过闭包或函数设置默认属性值2. 存储属性的初始赋值类和结构体在创建实例时必须为所有存储属性设置合适的初始值。存储属性不能处于不确定的状态。你可以在构造器中为存储属性赋初值也可以在定义属性时直接设置默认值。// 方式一在定义时设置默认值 struct Rectangle { var width: Double 10.0 var height: Double 20.0 } // 方式二在构造器中赋值 struct Circle { var radius: Double init() { radius 1.0 // 在构造器中赋值 } } // 创建实例 let rect Rectangle() // width 10.0, height 20.0 let circle Circle() // radius 1.03. 自定义构造器自定义构造器在调用时通过构造器参数传入自定义的初始化参数。struct Celsius { var temperatureInCelsius: Double // 自定义构造器 init(fromFahrenheit fahrenheit: Double) { temperatureInCelsius (fahrenheit - 32.0) / 1.8 } init(fromKelvin kelvin: Double) { temperatureInCelsius kelvin - 273.15 } // 不带参数标签的构造器 init(_ celsius: Double) { temperatureInCelsius celsius } } let boilingPointOfWater Celsius(fromFahrenheit: 212.0) print(boilingPointOfWater.temperatureInCelsius) // 100.0 let freezingPointOfWater Celsius(fromKelvin: 273.15) print(freezingPointOfWater.temperatureInCelsius) // 0.0 let bodyTemperature Celsius(37.0) print(bodyTemperature.temperatureInCelsius) // 37.04. 默认构造器与逐一成员构造器4.1 默认构造器如果结构体或类的所有存储属性都有默认值且没有自定义构造器Swift 会自动提供一个无参数的默认构造器。class ShoppingListItem { var name: String? var quantity 1 var purchased false } // 使用默认构造器创建实例 var item ShoppingListItem() item.name Milk print(item.quantity) // 14.2 逐一成员构造器结构体如果没有自定义构造器会自动获得一个逐一成员构造器即使存储属性没有默认值。struct Size { var width 0.0 var height 0.0 } // 使用逐一成员构造器 let twoByTwo Size(width: 2.0, height: 2.0) let zeroByTwo Size(height: 2.0) // width 使用默认值 0.0 let zeroByZero Size() // 两个属性都使用默认值5. 值类型与引用类型的构造器代理5.1 值类型的构造器代理值类型结构体和枚举的构造器可以通过调用其他构造器来完成实例的部分构造过程这称为构造器代理。struct Point { var x 0.0, y 0.0 } struct Rect { var origin Point() var size Size() // 自定义构造器 1 init() {} // 自定义构造器 2 init(origin: Point, size: Size) { self.origin origin self.size size } // 自定义构造器 3 - 通过构造器代理调用 init(origin:size:) init(center: Point, size: Size) { let originX center.x - (size.width / 2) let originY center.y - (size.height / 2) self.init(origin: Point(x: originX, y: originY), size: size) } } // 使用不同的构造器 let basicRect Rect() let originRect Rect(origin: Point(x: 2.0, y: 2.0), size: Size(width: 5.0, height: 5.0)) let centerRect Rect(center: Point(x: 4.0, y: 4.0), size: Size(width: 3.0, height: 3.0))5.2 类的构造过程类的构造过程涉及两个阶段确保所有存储属性都能正确初始化阶段一从子类到父类为每个存储属性设置初始值阶段二从父类到子类给每个类一次机会在新实例准备使用之前进一步自定义存储属性class Vehicle { var numberOfWheels 0 var description: String { return \(numberOfWheels) wheel(s) } } class Bicycle: Vehicle { override init() { super.init() // 调用父类构造器 numberOfWheels 2 // 在阶段二自定义属性 } } class Hoverboard: Vehicle { var color: String // 指定构造器 init(color: String) { self.color color // 这里隐式调用了 super.init() } // 便利构造器 convenience init() { self.init(color: Silver) } } let bicycle Bicycle() print(bicycle.description) // 2 wheel(s) let hoverboard Hoverboard(color: Red) print(hoverboard.color) // Red6. 可失败构造器与必要构造器6.1 可失败构造器可失败构造器可以创建特定类型的可选实例在初始化失败时返回nil。struct Animal { let species: String // 可失败构造器 init?(species: String) { if species.isEmpty { return nil } self.species species } } let someCreature Animal(species: Giraffe) if let giraffe someCreature { print(An animal was initialized with \(giraffe.species)) } let anonymousCreature Animal(species: ) // anonymousCreature 是 nil6.2 必要构造器在类的构造器前添加required修饰符表明所有子类都必须实现该构造器。class SomeClass { required init() { // 构造器的实现 } } class SomeSubclass: SomeClass { // 子类必须实现必要构造器 required init() { // 构造器的实现 super.init() } }7. 通过闭包或函数设置默认属性值如果某个存储属性的默认值需要一些自定义设置可以使用闭包或全局函数为其提供默认值。class Chessboard { let boardColors: [Bool] { var temporaryBoard: [Bool] [] var isBlack false for i in 1...8 { for j in 1...8 { temporaryBoard.append(isBlack) isBlack !isBlack } isBlack !isBlack } return temporaryBoard }() func squareIsBlackAt(row: Int, column: Int) - Bool { return boardColors[(row * 8) column] } } let board Chessboard() print(board.squareIsBlackAt(row: 0, column: 1)) // true print(board.squareIsBlackAt(row: 7, column: 7)) // false8. 构造过程的最佳实践与常见陷阱8.1 最佳实践使用默认值尽可能在属性声明时提供默认值简化构造器构造器代理利用构造器代理减少重复代码两段式构造理解类的两段式构造过程避免在阶段一访问 self可失败构造器对于可能失败的初始化使用可失败构造器8.2 常见陷阱// 陷阱1在属性初始化之前访问 self class ProblematicClass { let value: Int init(value: Int) { // print(self.value) // 错误在 self 初始化之前访问 self.value value } } // 陷阱2忘记调用父类构造器 class Base { var baseValue: Int init(value: Int) { self.baseValue value } } class Derived: Base { var derivedValue: Int init(derivedValue: Int) { self.derivedValue derivedValue // 忘记调用 super.init(value:) // 需要在设置完所有属性后调用 super.init(value:) } }9. 总结Swift 的构造过程提供了强大而安全的初始化机制。通过理解存储属性的初始赋值、自定义构造器、构造器代理、可失败构造器等概念你可以编写出更加健壮和可维护的 Swift 代码。记住以下关键点所有存储属性在构造过程完成时必须被初始化值类型支持构造器代理类支持两段式构造过程可失败构造器为可能失败的初始化提供了安全的方式通过闭包设置默认属性值可以实现复杂的初始化逻辑掌握这些构造过程的知识将帮助你在 Swift 开发中避免常见的初始化错误编写出更加优雅和可靠的代码。