Swift 結構 (Structures)
結構 (Struct) 是 Swift 中建構程式碼的基石。不同於其他語言 (如 Objective-C 或 Java) 將 Class 視為一等公民,Swift 非常強調 Struct 的使用。在現代的 iOS 開發 (特別是 SwiftUI) 中,你會發現絕大多數的 View、Model 甚至 ViewModel 都是使用 Struct 定義的。
定義結構
使用 struct 關鍵字來定義一個結構。結構可以包含:
- 屬性 (Properties):儲存數值。
- 方法 (Methods):提供功能。
struct Resolution {
var width = 0
var height = 0
// 定義一個方法來計算總像素
func totalPixels() -> Int {
return width * height
}
}
自帶初始化器 (Memberwise Initializer)
Struct 有一個非常貼心的特性:Swift 編譯器會自動為你產生一個「成員逐一初始化器」。你不需要像 Class 那樣手動寫 init 方法。
// 自動產生的初始化器
let vga = Resolution(width: 640, height: 480)
// 如果屬性有預設值,你雖然可以省略,但 Memberwise Init 通常還是會要求填入
// 除非你自己定義了 init
如果你想要自定義初始化邏輯,也可以自己寫 init:
struct Celsius {
var temperatureInCelsius: Double
init(fromFahrenheit fahrenheit: Double) {
temperatureInCelsius = (fahrenheit - 32.0) / 1.8
}
init(fromKelvin kelvin: Double) {
temperatureInCelsius = kelvin - 273.15
}
}
值型別 (Value Types) 的意義
Struct 是值型別 (Value Type)。這在 Swift 中是一個非常核心的概念。
什麼是「值型別」?
簡單來說,當你把一個 Struct 賦值給另一個變數,或是傳遞給函式時,系統會複製 (Copy) 一份完整的內容。
生活類比: 想像你有一份 Excel 檔案。當你把這份檔案 Email 給同事時,同事收到的是一份副本。他在副本上做的任何修改 (例如刪除一行資料),完全不會影響你電腦裡原本的那份檔案。這就是 Value Type。
struct Resolution {
var width = 0
var height = 0
}
let hd = Resolution(width: 1920, height: 1080)
var cinema = hd // 這裡發生了「複製」行為,cinema 是一份獨立的副本
cinema.width = 2048 // 修改 cinema 的寬度
print("cinema width: \(cinema.width)") // 2048
print("hd width: \(hd.width)") // 1920 (原值完全不受影響)
Mutating 方法
因為 Struct 是值型別,Swift 預設不允許在實體方法 (Instance Method) 中修改自身的屬性 (因為這等同於修改了「值」本身)。
如果你需要在方法中修改屬性,必須將該方法標記為 mutating:
struct Point {
var x = 0.0, y = 0.0
// 必須加上 mutating 關鍵字,否則編譯錯誤
mutating func moveBy(x deltaX: Double, y deltaY: Double) {
x += deltaX
y += deltaY
}
}
var somePoint = Point(x: 1.0, y: 1.0)
somePoint.moveBy(x: 2.0, y: 3.0) // x 變為 3.0, y 變為 4.0
注意:如果你宣告實體為常數 (
let),即使方法標記為 mutating 也無法呼叫,因為常數本來就不能被修改。為什麼 Swift (和 SwiftUI) 偏愛 Struct?
- 安全性 (Safety):因為值是複製的,你不需要擔心資料在不知情的情況下被程式的其他部分修改。這在多執行緒環境下特別重要。
- 效能 (Performance):Struct 通常分配在 Stack (堆疊) 上,存取速度比分配在 Heap (堆積) 上的 Class 快得多。
- 不可變性 (Immutability):透過
let宣告,我們可以輕鬆確保資料的不可變性,這讓程式邏輯更清晰、預測性更高。
事實上,Swift 內建的 Int, Double, String, Array, Dictionary 全都是 Struct!這證明了 Struct 的強大與高效。