談談程式 3 — Class vs Structure

圖 1–1

在程式編撰中,有兩種建立物件的方法,分別為 Class (類) 與 Structure (結構)。編撰程式中常要思考使用哪一種方法最適合,首先要先了解這兩者的功能及差異。

由於兩種的功能其實大同小異,通常會直接從兩者之間的差異來認識。最主要的差異就如同圖 1–1,一種是 Value Type、 一種是 Reference Type。

Value Type & Reference Type

Structure 屬於 Value Type、Class 屬於 Reference Type。

Value Type 是跟 “值” 有直接關係的,當Structure 的實例被複製時,會另外創造一個記憶體空間,把整個實例這個值放到新創造的記憶體中。

Reference Type 是跟 “記憶體位置” 有關,當Class 的物件被複製時,並不會額外生成新的記憶體空間,被複製的是指該物件的記憶體位置,實質上物件還是同一個。

以下用程式舉例

struct PersonStruct {
var name: String
var age: Int
}
class PersonClass {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
}

可以看到在使用 Class 時要將屬性初始化,宣告 Structure 時有無初始化都行

在創造 PersonStruct 的實例時 name 初始值為 “Chris”,這時產生了一個記憶體空間。

將 structPersonA 直接複製給 structPersonB ,創造了另一個記憶體空間。

把複製過來的 structPersonB 的 name 屬性改為 “Anna”

印出兩個屬性可以發現名字是不一樣的,那是因為 structure 為 value 型態,更改的屬性為當下的值,並不會影響另外一個記憶體空間裡的值。

創造 Class 的物件為 classPersonA 後,直接將 classPersonA 給 classPersonB。

將 classPersonB 的 name 屬性改為 Anna

印出兩個屬性的值都是 Anna,是因為 Class 為 Reference 型態。

classPersonA 跟 classPersonB 都指到 PersonClass 這個記憶體位置,意思使兩者都代表同一個物件並沒有複製的效果。

繼承

兩者中還有個是否可以 “繼承” 差異

另外宣告一個 SuperPersonClass,裡面宣告一個 fly 的方法。

讓 PersonClass 繼承 SuperPersonClass,當創建 PersonClass 物件後,也可以使用 SuperPersonClass 的 fly 方法。

另外宣告一個 SuperPersonStruct,如果讓 PersonStruct 繼承 SuperPersonStruct 會發生錯誤。

雖然 Structure 無法享有繼承的能力,但有類似的方法像是宣告 Protocol 來讓 PersonStruct 遵從這個 Protocol,即可擁有 fly 能力。

Structure 與 Class 的使用時機

這邊我的主觀判斷是,如果針對個別資料上的儲存與改變時,像是製作選擇題或是聯絡人,每個值都會有所改變,就會傾向使用 Structure。

如果資料需要大量的在頁面傳遞,或者是需要繼承原本 UIKit 或其他 Class ,會偏向使用 Class。

兩者都有其好處,個人認為不會特別取代哪一方,多練習使用才會抓到兩者擇一的精髓。

--

--