Swift 結構與類別 (Structures and Classes)

結構 (Struct) 和類別 (Class) 是 Swift 中建構程式碼基石的通用、靈活的構造。一般來說,它們的功能非常相似:

  • 都可以定義屬性 (Properties) 來儲存值
  • 都可以定義方法 (Methods) 來提供功能
  • 都可以定義下標 (Subscripts)
  • 都可以定義初始化器 (Initializers)
  • 都可以被擴展 (Extensions)
  • 都可以遵循協定 (Protocols)

語法比較

struct Resolution {
    var width = 0
    var height = 0
}

class VideoMode {
    var resolution = Resolution()
    var interlaced = false
    var frameRate = 0.0
    var name: String?
}

核心差異:Value Type vs Reference Type

這是 Struct 和 Class 最根本的區別,理解這一點非常重要。

結構是值型別 (Value Types)

當你將 Struct 賦值給一個變數,或將其傳遞給函式時,它的值會被複製 (Copied)

let hd = Resolution(width: 1920, height: 1080)
var cinema = hd

cinema.width = 2048 // 修改 cinema 的寬度

print("cinema width: \(cinema.width)") // 2048
print("hd width: \(hd.width)")         // 1920 (原值不受影響)

Swift 中幾乎所有的基本型別 (Int, String, Array, Dictionary) 其實都是 Struct。

類別是參考型別 (Reference Types)

當你將 Class 賦值給一個變數時,不會複製,而是傳遞參考 (Reference) (也就是記憶體位置)。多個變數可能指向同一個實例。

let tenEighty = VideoMode()
tenEighty.frameRate = 25.0

let alsoTenEighty = tenEighty
alsoTenEighty.frameRate = 30.0 // 修改了也會影響 tenEighty

print(tenEighty.frameRate) // 30.0 (被改變了!)

恆等運算子 (Identity Operators)

因為 Class 是參考,我們有時需要判斷兩個變數是否指向同一個實例,這時使用 === (恆等) 和 !== (不恆等):

if tenEighty === alsoTenEighty {
    print("指向同一個實例")
}

如何選擇?

Swift 官方建議:預設情況下,優先使用 Struct。

請在以下情況才使用 Class:

  1. 你需要繼承 (Inheritance) 的特性。
  2. 你需要與 Objective-C 互操作 (Interoperability)。
  3. 你需要控制物件的識別 (Identity),即需要共享同一個實例的狀態。

在現代 Swift 開發 (尤其是 SwiftUI) 中,Struct 的使用比例遠高於 Class。