本文參考
類和結(jié)構(gòu)體(Classes and Structures)
前幾天收到一個(gè)面試邀請(qǐng),其中一個(gè)面試官直接問Swift中“枚舉和結(jié)構(gòu)體”有什么區(qū)別,當(dāng)時(shí)直接就給問懵逼了。想了半天也沒想出來這兩樣?xùn)|西需要有區(qū)別嗎,貌似就不是一類東西,感覺心虛,回來之后特意找來Swift基礎(chǔ)查看了一下,我想當(dāng)時(shí)面試官問的應(yīng)該是“類和結(jié)構(gòu)體”的區(qū)別吧,純屬猜測(cè)。言歸正傳:
在swift中類和結(jié)構(gòu)體有許多相似之處,例如相同的定義格式等??偨Y(jié)之,共同之處如下:
定義屬性用于存儲(chǔ)值
定義方法用于提供功能
定義下標(biāo)操作使得可以通過下標(biāo)語(yǔ)法來訪問實(shí)例所包含的值
定義構(gòu)造器用于生成初始化值
通過擴(kuò)展以增加默認(rèn)實(shí)現(xiàn)的功能
實(shí)現(xiàn)協(xié)議以提供某種標(biāo)準(zhǔn)功能
與結(jié)構(gòu)體相比,類的功能更加強(qiáng)大,
繼承允許一個(gè)類繼承另一個(gè)類的特征
類型轉(zhuǎn)換允許在運(yùn)行時(shí)檢查和解釋一個(gè)類實(shí)例的類型
析構(gòu)器允許一個(gè)類實(shí)例釋放任何其所被分配的資源
引用計(jì)數(shù)允許對(duì)一個(gè)類的多次引用
定義語(yǔ)法
class SomeClass{
// class definition goes here類的定義方法
}
struct SomeStructure{
// structure definition goes here結(jié)構(gòu)體的定義方法
}

可以看出,在VideoMode的類中使用了Resolution結(jié)構(gòu)體實(shí)例
類和結(jié)構(gòu)體實(shí)例的生成
上述只是定義了一個(gè)類和結(jié)構(gòu)體,結(jié)構(gòu)體和類的使用需要對(duì)齊進(jìn)行實(shí)例化,生成結(jié)構(gòu)體和類的實(shí)例非常相似:
let someResolution =Resolution()
let someVideoMode =VideoMode()
對(duì)于其屬性的訪問,可以通過點(diǎn)(.)語(yǔ)法來進(jìn)行,例如:
print("The width of someResolution is\(someResolution.width)")
// 輸出 "The width of someResolution is 0"
print("The width of someVideoMode is\(someVideoMode.resolution.width)")
// 輸出 "The width of someVideoMode is 0"
接著需要介紹兩個(gè)非常有用的名詞:
值類型 ? 引用類型
值類型:
值類型被賦予給一個(gè)變量、常量或者被傳遞給一個(gè)函數(shù)的時(shí)候,其值會(huì)被拷貝。在 Swift 中,所有的結(jié)構(gòu)體和枚舉類型都是值類型。這意味著它們的實(shí)例,以及實(shí)例中所包含的任何值類型屬性,在代碼中傳遞的時(shí)候都會(huì)被復(fù)制。
引用類型:
與值類型不同,引用類型在被賦予到一個(gè)變量、常量或者被傳遞到一個(gè)函數(shù)時(shí),其值不會(huì)被拷貝。因此,引用的是已存在的實(shí)例本身而不是其拷貝。
總而言之,如何選擇使用類或者結(jié)構(gòu)體:
類和結(jié)構(gòu)體的選擇
在你的代碼中,你可以使用類和結(jié)構(gòu)體來定義你的自定義數(shù)據(jù)類型。
然而,結(jié)構(gòu)體實(shí)例總是通過值傳遞,類實(shí)例總是通過引用傳遞。這意味兩者適用不同的任務(wù)。當(dāng)你在考慮一個(gè)工程項(xiàng)目的數(shù)據(jù)結(jié)構(gòu)和功能的時(shí)候,你需要決定每個(gè)數(shù)據(jù)結(jié)構(gòu)是定義成類還是結(jié)構(gòu)體。
按照通用的準(zhǔn)則,當(dāng)符合一條或多條以下條件時(shí),請(qǐng)考慮構(gòu)建結(jié)構(gòu)體:
該數(shù)據(jù)結(jié)構(gòu)的主要目的是用來封裝少量相關(guān)簡(jiǎn)單數(shù)據(jù)值。
有理由預(yù)計(jì)該數(shù)據(jù)結(jié)構(gòu)的實(shí)例在被賦值或傳遞時(shí),封裝的數(shù)據(jù)將會(huì)被拷貝而不是被引用。
該數(shù)據(jù)結(jié)構(gòu)中儲(chǔ)存的值類型屬性,也應(yīng)該被拷貝,而不是被引用。
該數(shù)據(jù)結(jié)構(gòu)不需要去繼承另一個(gè)既有類型的屬性或者行為。
舉例來說,以下情境中適合使用結(jié)構(gòu)體:
幾何形狀的大小,封裝一個(gè)width屬性和height屬性,兩者均為Double類型。
一定范圍內(nèi)的路徑,封裝一個(gè)start屬性和length屬性,兩者均為Int類型。
三維坐標(biāo)系內(nèi)一點(diǎn),封裝x,y和z屬性,三者均為Double類型。
在所有其它案例中,定義一個(gè)類,生成一個(gè)它的實(shí)例,并通過引用來管理和傳遞。實(shí)際中,這意味著絕大部分的自定義數(shù)據(jù)構(gòu)造都應(yīng)該是類,而非結(jié)構(gòu)體。