與值類型不同,引用類型在被賦予到一個變量,常量或者被傳遞到一個函數(shù)時,操作的并不是其拷貝。因此,引用的是已存在的實例本身而不是其拷貝。
請看下面這個示例,其使用了之前定義的VideoMode類:
let tenEighty = VideoMode()
tenEighty.resolution = hd
tenEighty.interlaced = true
tenEighty.name = "1080i"
tenEighty.frameRate = 25.0
以上示例中,聲明了一個名為tenEighty的常量,其引用了一個VideoMode類的新實例。在之前的示例中,這個視頻模式(video mode)被賦予了HD分辨率(1920*1080)的一個拷貝(hd)。同時設置為交錯(interlaced),命名為“1080i”。最后,其幀率是25.0幀每秒。
然后,tenEighty 被賦予名為alsoTenEighty的新常量,同時對alsoTenEighty的幀率進行修改:
let alsoTenEighty = tenEighty
alsoTenEighty.frameRate = 30.0
因為類是引用類型,所以tenEight和alsoTenEight實際上引用的是相同的VideoMode實例。換句話說,它們只是同一個實例的兩種叫法。
下面,通過查看tenEighty的frameRate屬性,我們會發(fā)現(xiàn)它正確的顯示了基本VideoMode實例的新幀率,其值為30.0:
println("The frameRate property of tenEighty is now \(tenEighty.frameRate)")
// 輸出 "The frameRate property of theEighty is now 30.0"
需要注意的是tenEighty和alsoTenEighty被聲明為常量((constants)而不是變量。然而你依然可以改變tenEighty.frameRate和alsoTenEighty.frameRate,因為這兩個常量本身不會改變。它們并不儲存這個VideoMode實例,在后臺僅僅是對VideoMode實例的引用。所以,改變的是被引用的基礎VideoMode的frameRate參數(shù),而不改變常量的值。
因為類是引用類型,有可能有多個常量和變量在后臺同時引用某一個類實例。(對于結構體和枚舉來說,這并不成立。因為它們作值類型,在被賦予到常量,變量或者傳遞到函數(shù)時,總是會被拷貝。)
如果能夠判定兩個常量或者變量是否引用同一個類實例將會很有幫助。為了達到這個目的,Swift 內建了兩個恒等運算符:
以下是運用這兩個運算符檢測兩個常量或者變量是否引用同一個實例:
if tenEighty === alsoTenTighty {
println("tenTighty and alsoTenEighty refer to the same Resolution instance.")
}
//輸出 "tenEighty and alsoTenEighty refer to the same Resolution instance."
請注意“等價于”(用三個等號表示,===) 與“等于”(用兩個等號表示,==)的不同:
當你在定義你的自定義類和結構體的時候,你有義務來決定判定兩個實例“相等”的標準。在章節(jié)運算符函數(shù)(Operator Functions)中將會詳細介紹實現(xiàn)自定義“等于”和“不等于”運算符的流程。
如果你有 C,C++ 或者 Objective-C 語言的經(jīng)驗,那么你也許會知道這些語言使用指針來引用內存中的地址。一個 Swift 常量或者變量引用一個引用類型的實例與 C 語言中的指針類似,不同的是并不直接指向內存中的某個地址,而且也不要求你使用星號(*)來表明你在創(chuàng)建一個引用。Swift 中這些引用與其它的常量或變量的定義方式相同。