struct
struct 值引用
在swift中,類型引用和值引用的區(qū)別在于苟穆,對于類型引用(class reference),將變量a賦值給變量b雳旅,即b = a,這樣的賦值語句僅僅將b的指針與a的指針一樣抵拘,指向同一塊內(nèi)存區(qū)域型豁,此時改變b的值,a也會跟著改變充尉;而對于值引用(value reference)衣形,賦值語句b = a處理的過程是開辟一個新的內(nèi)存b,將a變量的內(nèi)容拷貝后存放到內(nèi)存b倒源,這時a和b完全沒有關(guān)系的兩個變量句狼,對b的改變不會影響到a,反之亦然鲜锚。
// struct value reference, class reference
func valueCopyValid() -> Void {
var personXm = Person(name: "xiao-min", age: 6, sex: .man)
var personXmCopy = personXm
personXmCopy.age = 20
print("\(personXm) : \(personXmCopy)")
}
print:
Person(name: "xiao-min", age: 6, sex: swift_learn_keyword.Sex.man)
Person(name: "xiao-min", age: 20, sex: swift_learn_keyword.Sex.man)
struct和class的主要區(qū)別,
- struct是值引用旺隙,而class是類型引用
- struct沒有繼承的功能骏令,class有繼承功能
struct和class這兩個基本層面的區(qū)別,體現(xiàn)了區(qū)別于Objective-C語言榔袋,swift語言帶來了全新的天翻地覆的改變。
首先說第一點區(qū)別妥粟,從swift的更新和struct不斷完善來看勾给,蘋果公司更加推薦使用struct來代替class滩报,因為struct值引用和class類型引用這點區(qū)別播急,保證使用struct編碼能寫出更加安全可靠的代碼。為什么這樣說呢桩警,class類型引用在賦值時是將變量指向了同一塊內(nèi)存地址,這在一個長時間的跨度上會帶來一些意想不到的問題握截,試想一個簡單的例子,viewControllerA持有一個NSMutableArray數(shù)組mutalbeArray川蒙,它包含100條user信息长已,此時將mutableArray賦值給viewControllerB,對于viewControllerB而言康聂,它僅僅需要前10條user信息恬汁,所以它將mutableArray多余的信息刪除了,這樣一個腦殘的操作導致了viewControllerA模塊展示錯誤和潛在的邏輯錯誤氓侧。而使用struct值引用則不會出現(xiàn)這樣的問題导狡。
第二點區(qū)別,struct沒有繼承的功能旱捧,這是因為swift在本質(zhì)上來說是面向協(xié)議(Protocol Oriented)的語言,struct沒有也不需要繼承的功能氓癌,為了實現(xiàn)某個功能,struct去服從并實現(xiàn)某個協(xié)議就即可贫橙,從一個較高的層次來看贪婉,struct+protocol是構(gòu)成swift面向協(xié)議語言的兩個基石。這一點不在本文討論范圍卢肃,不再贅述疲迂。
為什么要使用struct呢星压?總結(jié)就是struct可以保證代碼更加安全可靠,以及struct+protocol更加切合swift面向協(xié)議編程的初衷鬼譬。
enum
/*
- =左邊的值是枚舉值,例如 MON
- =右邊的值在swift中稱為 RawValue(原始值)逊脯,例如 "MON"
- 兩者的關(guān)系為:case 枚舉值 = rawValue原始值
*/
enum Week: String{
case MON = "MON"
case TUE = "TUE"
case WED = "WED"
case THU = "THU"
case FRI = "FRI"
case SAT = "SAT"
case SUN = "SUN"
}
enum Week1: String{
case MON, TUE, WED = "WED", THU, FRI, SAT, SUN
}
//<!--Int類型-->
//MON是從0開始一次遞推优质,而WED往后是從10開始一次遞推
enum Week2: Int{
case MON, TUE, WED = 2, THU, FRI, SAT, SUN
}
enum Week3 {
case work(day: Week2)
case free(day: Week2)
}
mutating
struct Person {
var name: String
var age: Int
var sex: Sex
init(name: String, age: Int, sex: Sex) {
self.age = age
self.name = name
self.sex = sex
}
func string() -> String {
return "\(name) - \(age) - \(sex)"
}
func addAge(count: Int) {
self.age += count
}
}
error: Left side of mutating operator isn't mutable: 'self' is immutable Mark method 'mutating' to make 'self' mutable
說白了 struct/enum 內(nèi)部聲明的屬性是內(nèi)部不可變的(與值引用又一定關(guān)系),需要內(nèi)部修改值那么需要申明 mutating 關(guān)鍵詞進行標記
struct Person {
var name: String
var age: Int
var sex: Sex
init(name: String, age: Int, sex: Sex) {
self.age = age
self.name = name
self.sex = sex
}
func string() -> String {
return "\(name) - \(age) - \(sex)"
}
mutating func addAge(count: Int) {
self.age += count
}
}