首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

Swift 值類型與引用類型深度解析:選擇指南與效能影響

     編輯:更多程式設計知識

Swift 類型系統核心區分為值類型與引用類型,理解兩者語義差異對於寫出正確、高效能、執行緒安全的程式碼至關重要。本文深入剖析複製語義、變異安全性、選擇準則與進階考量。

核心定義

分類關鍵字複製語義資料共享典型代表
值類型struct, enum, tuple深層複製 (獨立副本)無Int, String, Array, Dictionary, Set, 自訂 Struct
引用類型class淺層複製 (共享實例)是自訂 Class, 閉包, 函式型別

複製行為實測

值類型:獨立副本


struct Point { var x: Int; var y: Int }
var a = Point(x: 1, y: 2)
var b = a           // 複製:建立獨立副本
b.x = 10
print(a.x, b.x)     // 1 10 ← a 不受影響

引用類型:共享實例


class PointClass { var x: Int; var y: Int }
var a = PointClass(x: 1, y: 2)
var b = a           // 複製:共享同一實例
b.x = 10
print(a.x, b.x)     // 10 10 ← a 也被修改!

變異與執行緒安全性

  • 值類型:天然執行緒安全。傳遞給其他執行緒時自動複製,無競態條件風險。let 常數保證不可變。
  • 引用類型:共享可變狀態需手動同步 (DispatchQueue, NSLock, actor Swift 5.5+)。
  • 不可變引用類型:若 Class 所有屬性皆為 let 且無修改方法,實務上可視為值語義,但語言不強制。

選擇準則:何時用值類型?

✅ 符合以下條件優先用 Struct/Enum:

  1. 需要 == 比較資料內容而非身分。
  2. 複製後期望獨立狀態,修改副本不影響原本。
  3. 資料在多執行緒間傳遞,追求無鎖安全。
  4. 型別語意為「值」而非「實體」:座標、範圍、顏色、UUID、貨幣金額。
  5. 輕量級、無身分識別、無繼承需求。

選擇準則:何時用引用類型?

✅ 符合以下條件用 Class:

  1. 需要 === 比較實例身分 (同一物件)。
  2. 需要共享可變狀態:單例、快取、觀察者模式、Delegate。
  3. 需要繼承與多型 (Struct 不支援繼承)。
  4. 型別語意為「實體」:視圖控制器、資料模型、網路管理器、資料庫連線。
  5. 需與 Objective-C 互通 (NSObject 子類別)。
  6. 需要 deinit 執行清理邏輯。

Swift 標準庫值類型設計哲學

Array、String、Dictionary、Set 皆為值類型,實作寫時複製:


var a = [1, 2, 3]
var b = a           // O(1) 共享底層緩衝區
b.append(4)         // 觸發複製,a 不受影響
print(a, b)         // [1,2,3] [1,2,3,4]

此設計兼顧效能 (未修改時零複製) 與安全性 (修改時語義如值類型)。

進階:盒子化與間接層

若 Struct 過大導致複製開銷大,可用類別包裝:


final class Box { var value: LargeStruct }
var a = Box(value: large)
var b = a           // 僅複製參考,極快

或使用 @frozen (庫演進模式) 固定記憶體佈局。

常見誤區

誤區事實
Class 傳遞是「傳址呼叫」Swift 只有「傳值呼叫」,Class 傳遞的是「參考的值」
Struct 不能有可變方法可用 mutating 關鍵字修飾方法
Enum 不能有關聯值Enum 強大支援關聯值、原始值、遞迴
值類型一定比 Class 快大型 Struct 複製開銷可能超過 Class 參考傳遞

最佳實務總結

  1. 預設用 Struct,除非明確需要 Class 特性 (身分、共享狀態、繼承、Objective-C 互通)。
  2. 定義 Struct 時考慮 Equatable/Hashable 協議實作。
  3. 大型資料結構評估 Copy-on-Write 行為,必要時用 Class 包裝。
  4. 公開 API 設計時,文件化說明型別語意 (值/引用) 與執行緒安全保證。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved