枚舉enum和結構體與C中的類似,主要用于别名定義一些有限的類型和一些複雜的資料結構。但是在swift中的枚舉呢除了具有基本的類型限制和别名使用外還可以進行繼承,遵守協定。
結構體struct和後續的類相似,但是結構體是一個值拷貝的資料類型。
一:枚舉
1:枚舉的聲明
聲明一個枚舉需要使用關鍵字enum;
enum Toward{
case Forward
case Back
case Left
case Right
}
case 關鍵字表示增加一個枚舉定義值,當然,還可以把所有的枚舉值寫在一行當中。
enum Toward{
case Forward , Back , Left , Right
}
2:枚舉值
枚舉元素隻有在指定了類型之後才可能有原始值,可以用 toRaw() 的方法擷取枚舉的原始值。
例如:
let goTo = Toward.Left //擷取枚舉中的某個定義的值
print(goTo.toRaw()) //錯誤的。因為枚舉中并沒有對每個元素賦相應的值。
在以上的定義中,四個枚舉值并沒有被賦具體的值(這與C語言中不同的地方)
如果要給枚舉中定義的所有的枚舉值指派,需要指定枚舉的類型。
enum Toward:Int {
case Forward , Back , Left , Right
}
這時,枚舉中的四個元素就被預設指派從0 開始的整數。
let goTo = Toward.Left
print(goTo.toRaw())
//輸出為2
也可以手動給每個枚舉元素指派
enum Toward:Int {
case Forward = 2, Back , Left = 20 , Right
}
當給某一個元素指派後,後面的元素會根據該元素的值依次指派。
let goTo = Toward.Back
print(goTo.toRaw())
//輸出為3
print (Toward.Right.toRaw())
//輸出為21
在swift中,枚舉還可以被指定為其他類型,例如:String
enum Toward:String {
case Forward = “a”, Back = “b”, Left = “K” , Right = “F”
}
print (Toward.Right.toRaw())
//輸出F
注意咯:如果指定枚舉的類型為非Int,需要給每個枚舉元素指定值,并且每一個值都必須是唯一的。像下面這樣就有問題。
enum Toward:Double{
case Forward = 1.2
case Back = 1.2 //錯誤,因為1.2這個值已經存在
case Left = 2.5
case Right
//錯誤,因為這個枚舉被指定為Double類型,必須給每一個元素指定值
}
3:通過 fromRaw() 方法可以由原始值得到枚舉中對應的定義元素
enum Toward:Int {
case Forward = 2, Back , Left = 20 , Right
}
let toDirect = Toward.fromRaw(21)
//這裡 toDirect 的類型是可選Toward,因為在枚舉定義中不一定存在原始值為21的成員,此時 toDirect 的值為 Toward.Right
4:枚舉的使用方法
枚舉使用的場景較多,但是用法相對單一,一般都是用來表示一組互相關聯的情況,或者數值。
//定義一個枚舉
enum TowardEvent {
case TouchUpInSide
case TouchDown
case DoubleClick
}
//定義一個事件,并指定其類型為TowardEvent
var event:TowardEvent
//定義event的事件類型為單擊
event = TowardEvent .TouchUpInSide
//處理事件
switch event {
case.TouchUpInSide:
print(:按鈕被單擊")
case.TouchDown:
print("按鈕被按下")
case.DoubleClick:
print("按鈕被輕按兩下")
}
//輸出:按鈕被單擊
在switch-case中必須覆寫所有枚舉的成員情況。如果某些情況不需要單獨處理,則必須使用Default進行處理。
switch event {
case.TouchUpInSide:
print(:按鈕被單擊")
case.TouchDown:
print("按鈕被按下")
Default:
print ("其他情況")
}
二、結構體
結構體是用來儲存一個對象或者說一種事物的一組資訊,例如說:一個學生,有學号,姓名,性别等屬性。結構體與枚舉不同,一個變量被聲明為某一個枚舉類型後,它的值僅僅是枚舉類型中所定義的一組值中的一個,而一個變量聲明為結構體後,就包含了結構體中定義的所有值。
1:結構體的聲明和定義
可以用 struct 關鍵字來聲明一個結構體;
struct Student {
var sID : Int ; // 學号
var sName : String; // 姓名
var sSex : Bool; // 性别
var sPhone : String; // 電話
}
在結構體聲明時,也可以不指定屬性的類型,而是需要給每一個屬性指派,并通過類型識别擷取所有屬性的類型。
struct Student {
var sID = 0
var sName = " "
var sSex = true
var sPhone = " "
}
2:空參構造方法和全參構造方法 2.1:空參構造方法 var Li = Student ()
結構體的成員變量必須有初始值,是以用上面的方法定義一個結構體不能使用空參構造方法,因為沒有初始值,這樣會報錯。
2.2:全參構造方法 var Li = Student(sID:12 , SName : "王八", sSex : true , sPhone : "13131313131");
全參構造方法中必須對結構體中的每一個屬性進行指派,但這裡的字段必須按照順序進行,而且構造方法裡面的參數名字和字段名字要完全相同。 不管用哪一種構造方法,都可以用全參構造方法,但使用全參構造方法會把結構體預設的屬性值覆寫掉。
3:結構體的指派和取值
結構體可以屬性名稱對結構體執行個體屬性進行通路。這裡的結構和字段之間通過“ . ”文法來通路。
例如: print (Li.sName) // 輸出為:王八
在結構體執行個體化後,可以對屬性的值進行指派和修改。
var Zhang = Student(); Zhang.sName = “李四” print (Zhang.sName)
// 輸出:李四
對結構體屬性進行指派後,該屬性的值會被新值所覆寫。
var Zhang = Student(); Zhang.sName = “張三” Zhang.sName = “王五” print (Zhang.sName) // 輸出:王五
4:結構體的嵌套
在結構體的定義是可以嵌套的,比如:一個學生在一個班級上課,班級又是另外一個結構體,每個班級都有對應的老師。
現在,定義一個老師結構體。
struct Teacher{
var tID = 0 var tName = “”
}
再定義一個班級結構體。
struct ClassRoom{
var ClassId = 0
var ClassName = “”
var ClassCharge = Teacher() //老師
}
定義一個學生結構體。
struct Student{
var stuId = 0
var ClassInfo = ClassRoom()
var stuName = " "
var stuSex = true
var stuPhone = " "
}
現在定義一個學生,對學生的資訊進行指派:
var Zhang = Student()
Zhang.stuName = “張三”
Zhang.ClassInfo.ClassName = "Swift語言"
Zhang.ClassInfo.ClassCharge.tName = "馬雲"
print ("學生:"+Zhang.stuName +"班級:"+Zhang.ClassInfo.ClassName+"老師:"+Zhang.ClassInfo.ClassCharge.tName)
//輸出:學生:張三 班級:Swift語言 老師:馬雲
在結構體的嵌套中,對執行個體屬性的通路使用鍊式方式進行通路。也就是結構體中可以一層一層的進行嵌套讀寫操作。
5:結構體是值拷貝類型
值類型是相對于引用類型來說的,是指兩個結構體執行個體變量之間進行指派時,是對結構體所有内容進行内容拷貝。
var Ma = Zhang
Ma.stuName = "馬化騰"
print(Ma.stuName)
print(Zhang.stuName)
//輸出:
//馬化騰
//張三
*****************************************************************************************************************************************886