類和結(jié)構(gòu)體
可以通過使用常量、變量和函數(shù)完全相同的語法來定義屬性和方法向類和結(jié)構(gòu)添加功能脯倒。
Swift不需要為自定義類和結(jié)構(gòu)創(chuàng)建單獨(dú)的接口和實(shí)現(xiàn)文件实辑,只需要在單個(gè)文件中定義一個(gè)類或結(jié)構(gòu)體Swift會(huì)自動(dòng)形成對(duì)其他代碼可用的外部接口。
<br />
比較類和結(jié)構(gòu)體
類和結(jié)構(gòu)體的共同之處:
- 定義屬性以存儲(chǔ)值
- 定義方法以提供功能
- 定義下標(biāo)使用下標(biāo)語法提供對(duì)其值的訪問
- 定義初始化器以設(shè)置其初始狀態(tài)
- 擴(kuò)展默認(rèn)實(shí)現(xiàn)的功能
- 遵循協(xié)議以提供某種特定功能
類具有的附加功能:
- 繼承另一個(gè)類的特性
- 類型轉(zhuǎn)換使得在運(yùn)行時(shí)檢查和解釋類實(shí)例的類型
- 析構(gòu)器以釋放其內(nèi)存
- 引用計(jì)數(shù)允許對(duì)類實(shí)例的多個(gè)引用
注意
結(jié)構(gòu)體是值類型藻丢,且沒有引用計(jì)數(shù)剪撬,類是引用類型。
<br />
定義語法
類和結(jié)構(gòu)體定義語法類似悠反,分別使用class和struct關(guān)鍵字残黑。
class SomeClass {
// class definition goes here
}
struct SomeStructure {
// structure definition goes here
}
注意
類和結(jié)構(gòu)體的類型名采用首字母大寫的駝峰命名法,屬性和方法采用小寫的斋否。
類和結(jié)構(gòu)體的定義示例:
struct Resolution {
var width = 0
var height = 0
}
class VideoMode {
var resolution = Resolution()
var interlaced = false
var frameRate = 0.0
var name: String?
}
類和結(jié)構(gòu)體的實(shí)例
類和結(jié)構(gòu)體創(chuàng)建實(shí)例的語法也非常相似:
let someResolution = Resolution()
let someVideoMode = VideoMode()
類和結(jié)構(gòu)體創(chuàng)建實(shí)例都使用初始化器梨水,初始化器的最簡(jiǎn)單形式是使用類或結(jié)構(gòu)體的類型名,后跟空括號(hào)茵臭。這樣會(huì)將所有屬性初始化為默認(rèn)值疫诽。
訪問屬性
使用點(diǎn)語法訪問實(shí)例的屬性。
print("The width of someResolution is \(someResolution.width)")
// Prints "The width of someResolution is 0"
Swift可以直接設(shè)置結(jié)構(gòu)屬性的子屬性:
print("The width of someVideoMode is \(someVideoMode.resolution.width)")
// Prints "The width of someVideoMode is 0"
使用點(diǎn)語法給變量屬性設(shè)置新值:
someVideoMode.resolution.width = 1280
print("The width of someVideoMode is now \(someVideoMode.resolution.width)")
// Prints "The width of someVideoMode is now 1280"
結(jié)構(gòu)體類型的成員初始化器
所有結(jié)構(gòu)體會(huì)自動(dòng)生成一個(gè)成員初始化器笼恰,通過名稱將實(shí)例的屬性的初始化值傳遞給成員初始化器:
let vga = Resolution(width: 640, height: 480)
而類結(jié)構(gòu)不生成默認(rèn)的成員初始化器踊沸。
<br />
結(jié)構(gòu)體和枚舉是值類型
值類型是將值分配給變量或常量或?qū)⑵鋫鬟f給函數(shù)時(shí)復(fù)制其值的類型,改變其中一個(gè)而不會(huì)影響另一個(gè)社证。
Swift中的所有基本數(shù)據(jù)類型都是值類型逼龟,包括結(jié)構(gòu)體和枚舉。
說明結(jié)構(gòu)體是值類型的示例:
let hd = Resolution(width: 1920, height: 1080)
var cinema = hd
cinema.width = 2048
print("cinema is now \(cinema.width) pixels wide")
// Prints "cinema is now 2048 pixels wide"
print("hd is still \(hd.width) pixels wide")
// Prints "hd is still 1920 pixels wide"
說明枚舉是值類型的示例:
enum CompassPoint {
case north, south, east, west
}
var currentDirection = CompassPoint.west
let rememberedDirection = currentDirection
currentDirection = .east
if rememberedDirection == .west {
print("The remembered direction is still .west")
}
// Prints "The remembered direction is still .west"
<br />
類是引用類型
當(dāng)引用類型被分配給變量或常量或?qū)⑵鋫鬟f給函數(shù)時(shí)追葡,不會(huì)復(fù)制引用類型腺律,而是直接使用原實(shí)例的引用,這意味著修改其中一個(gè)值會(huì)直接反映到另一個(gè)值宜肉。
let tenEighty = VideoMode()
tenEighty.resolution = hd
tenEighty.interlaced = true
tenEighty.name = "1080i"
tenEighty.frameRate = 25.0
let alsoTenEighty = tenEighty
alsoTenEighty.frameRate = 30.0
print("The frameRate property of tenEighty is now \(tenEighty.frameRate)")
// Prints "The frameRate property of tenEighty is now 30.0"
上述的類實(shí)例都分配給了常量匀钧,修改實(shí)例的屬性對(duì)常量本身的值無影響,只是改變內(nèi)部的屬性谬返,未修改其引用之斯。
等于運(yùn)算符
使用等于運(yùn)算符判斷兩個(gè)常量或變量是否為相同的類實(shí)例,即同一個(gè)引用遣铝,有兩個(gè)相等運(yùn)算符:
- 想等 (===)
- 不想等 (!==)
`
if tenEighty === alsoTenEighty {
print("tenEighty and alsoTenEighty refer to the same VideoMode instance.")
}
// Prints "tenEighty and alsoTenEighty refer to the same VideoMode instance."
指針
C和Objective-C語言中使用指針來引用內(nèi)存地址佑刷,而Swift中引用某個(gè)引用類型的實(shí)例與指針類似,但不是直接指向內(nèi)存地址的指針酿炸,創(chuàng)建引用也不需要使用星號(hào)(*)瘫絮。
<br />
選擇類與結(jié)構(gòu)體
使用類和結(jié)構(gòu)體來定義復(fù)雜的自定義數(shù)據(jù)類型。
值類型和引用類型意味著結(jié)構(gòu)體和類適合于不同類型的任務(wù)填硕,依據(jù)以下原則考慮將一個(gè)數(shù)據(jù)類型定義為一個(gè)結(jié)構(gòu)體:
- 結(jié)構(gòu)體的主要目的是封裝一些相對(duì)簡(jiǎn)單的數(shù)據(jù)值麦萤。
- 在分配或傳遞該實(shí)例時(shí)鹿鳖,期望封裝的值將被復(fù)制會(huì)更加合理,而不是引用壮莹。
- 由結(jié)構(gòu)體存儲(chǔ)的任何屬性本身都是值類型翅帜,也將被復(fù)制。
- 結(jié)構(gòu)體不需要從另一個(gè)現(xiàn)有類型繼承屬性或方法垛孔。
以下為使用結(jié)構(gòu)體的一些好的例子:
- 幾何形狀的大小藕甩,封裝了均為Double類型的width屬性和height屬性。
- 代表一系列值的范圍周荐,封裝了均為Int類型的start屬性和length屬性狭莱。
- 3D坐標(biāo)系統(tǒng)的一個(gè)點(diǎn),封裝了均為Double類型的x概作,y和z屬性腋妙。
以上原則說明,
在所有其他條件下讯榕,定義為一個(gè)類骤素,并創(chuàng)建要通過引用進(jìn)行管理和傳遞的類的實(shí)例。愚屁,這意味著大多數(shù)自定義數(shù)據(jù)結(jié)構(gòu)應(yīng)該是類而不是結(jié)構(gòu)济竹。