Swift中類(lèi)和結(jié)構(gòu)體是構(gòu)建代碼所用的一種通用且靈活的構(gòu)造體??梢允褂猛耆嗤恼Z(yǔ)法規(guī)則來(lái)為類(lèi)和結(jié)構(gòu)體定義屬性(變量,常量)和添加方法,從而擴(kuò)展類(lèi)和結(jié)構(gòu)體的功能。
類(lèi)與結(jié)構(gòu)體對(duì)比
相同點(diǎn)
- 定義屬性用來(lái)存儲(chǔ)值;
- 定義方法用于提供功能;
- 定義下標(biāo)腳本用來(lái)允許使用下標(biāo)語(yǔ)法訪問(wèn)值;
- 定義初始化器用于初始化狀態(tài);
- 可以被擴(kuò)展來(lái)默認(rèn)所沒(méi)有的功能;
- 遵循協(xié)議來(lái)針對(duì)特定類(lèi)型提供標(biāo)準(zhǔn)功能;
struct Resolution {
var width = 0
var height = 0
}
class VideoMode {
var resolution = Resolution()
var interlaced = false
var frameRate = 0.0
var name: String?
}
let someResolution = Resolution()
let someVideoMode = VideoMode()
someVideoMode.resolution.width = 1280
print("The width of someResolution is \(someResolution.width)")
print("The width of someVideoMode is \(someVideoMode.resolution.width)")
不同點(diǎn)
- 繼承允許一個(gè)類(lèi)繼承另一個(gè)類(lèi)的特征;
- 類(lèi)型轉(zhuǎn)換允許你在運(yùn)行檢查和解釋一個(gè)類(lèi)實(shí)例的類(lèi)型;
- 反初始化器允許一個(gè)類(lèi)實(shí)例釋放任何其所被分配的資源;
- 引用計(jì)數(shù)允許不止一個(gè)對(duì)類(lèi)實(shí)例的引用;
值類(lèi)型與引用類(lèi)型
Swift 中所有的基本類(lèi)型——整數(shù),浮點(diǎn)數(shù),布爾量,字符串,數(shù)組和字典——都是值類(lèi)型,并且都以結(jié)構(gòu)體的形式在后臺(tái)實(shí)現(xiàn)。Swift中的結(jié)構(gòu)體和枚舉也是值類(lèi)型。
不同于值類(lèi)型,在引用類(lèi)型被賦值到一個(gè)常量,變量或者本身被傳遞到一個(gè)函數(shù)的時(shí)候它是不會(huì)被拷貝的。相對(duì)于拷貝,變量及被賦值的對(duì)象使用的是同一個(gè)對(duì)現(xiàn)存實(shí)例的引用。
特征運(yùn)算符
因?yàn)轭?lèi)是引用類(lèi)型,在后臺(tái)有可能有很多常量和變量都是引用到了同一個(gè)類(lèi)的實(shí)例。(相同這詞對(duì)結(jié)構(gòu)體和枚舉來(lái)說(shuō)并不是真的相同,因?yàn)樗鼈冊(cè)谫x予給常量,變量或者被傳遞給一個(gè)函數(shù)時(shí)總是被拷貝過(guò)去的。)
有時(shí)候找出兩個(gè)常量或者變量是否引用自同一個(gè)類(lèi)實(shí)例非常有用,為了允許這樣,Swift提供了兩個(gè)特點(diǎn)運(yùn)算符:
- 相同于 ( ===)
- 不相同于( !==)
“相同于”意味著兩個(gè)類(lèi)類(lèi)型常量或者變量引用自相同的實(shí)例;
“等于”意味著兩個(gè)實(shí)例的在值上被視作“相等”或者“等價(jià)”,某種意義上的“相等”,就如同類(lèi)設(shè)計(jì)者定義的那樣。
指針
Objective-C 中使用指針來(lái)引用內(nèi)存中的地址,Swift 中的常量或者變量指向某個(gè)實(shí)例的引用類(lèi)型和 C 中的指針類(lèi)似,但是這并不是直接指向內(nèi)存地址的指針,也不需要書(shū)寫(xiě)星號(hào)( *)來(lái)明確你建立了一個(gè)引用。相反,這些引用被定義得就像 Swift 中其他常量或者變量一樣。
如何選擇
選擇結(jié)構(gòu)體
- 結(jié)構(gòu)體的主要目的是為了封裝一些相關(guān)的簡(jiǎn)單數(shù)據(jù)值;
- 當(dāng)你在賦予或者傳遞結(jié)構(gòu)實(shí)例時(shí),有理由需要封裝的數(shù)據(jù)值被拷貝而不是引用;
- 任何存儲(chǔ)在結(jié)構(gòu)體中的屬性是值類(lèi)型,也將被拷貝而不是被引用;
- 結(jié)構(gòu)體不需要從一個(gè)已存在類(lèi)型繼承屬性或者行為;
大部分情況下自定義的數(shù)據(jù)結(jié)構(gòu)應(yīng)該是類(lèi),而不是結(jié)構(gòu)體。
Swift 的 String , Array 和 Dictionary類(lèi)型是作為結(jié)構(gòu)體來(lái)實(shí)現(xiàn)的,這意味著字符串,數(shù)組和字典在它們被賦值到一個(gè)新的常量或者變量,亦或者它們本身被傳遞到一個(gè)函數(shù)或方法中的時(shí)候,其實(shí)是傳遞了拷貝。
這種行為不同于基礎(chǔ)庫(kù)中的 NSString, NSArray和 NSDictionary,它們是作為類(lèi)來(lái)實(shí)現(xiàn)的,而不是結(jié)構(gòu)體。 NSString , NSArray 和 NSDictionary實(shí)例總是作為一個(gè)已存在實(shí)例的引用而不是拷貝來(lái)賦值和傳遞。
參考鏈接