一进每、枚舉
下面是用枚舉表示指南針?biāo)膫€方向的例子:
enum CompassPoint {
case North
case South
case East
case West
}
注意
與 C 和 Objective-C 不同,Swift 的枚舉成員在被創(chuàng)建時不會被賦予一個默認(rèn)的整型值命斧。在上面的CompassPoint例子中田晚,North,South国葬,East和West不會被隱式地賦值為0贤徒,1,2和3汇四。相反接奈,這些枚舉成員本身就是完備的值,這些值的類型是已經(jīng)明確定義好的CompassPoint類型通孽。
directionToHead = .South
switch directionToHead {
case .North:
print("Lots of planets have a north")
case .South:
print("Watch out for penguins")
case .East:
print("Where the sun rises")
case .West:
print("Where the skies are blue")
}
正如在控制流(Control Flow)中介紹的那樣序宦,在判斷一個枚舉類型的值時,switch語句必須窮舉所有情況背苦。如果忽略了.West這種情況互捌,上面那段代碼將無法通過編譯,因?yàn)樗鼪]有考慮到CompassPoint的全部成員行剂。強(qiáng)制窮舉確保了枚舉成員不會被意外遺漏秕噪。
當(dāng)不需要匹配每個枚舉成員的時候,你可以提供一個default分支來涵蓋所有未明確處理的枚舉成員:
let somePlanet = Planet.Earth
switch somePlanet {
case .Earth:
print("Mostly harmless")
default:
print("Not a safe place for humans")
}
下面是三種特殊的枚舉厚宰,涉及到關(guān)聯(lián)值腌巾、原始值、遞歸枚舉
1-1铲觉、關(guān)聯(lián)值
enum TestAssociatedValueEnumerations{
case TestIntType(Int,Int)
case TestStringType(String)
}
var testOne = TestAssociatedValueEnumerations.TestIntType(10, 5)
testOne = .TestStringType("testString")
/*
關(guān)聯(lián)值可以被提取出來作為 switch 語句的一部分澈蝙。你可以在switch的 case 分支代碼中提取每個關(guān)聯(lián)值作為一個常量(用let前綴)或者作為一個變量(用var前綴)來使用
*/
switch testOne{
case .TestIntType(let numberOne, let numberTwo):
print("one===\(numberOne),two====\(numberTwo)")
case .TestStringType(let stringTest):
print("string ====\(stringTest)")
}
但是這樣老有一個警告
switch condition evaluates to a constant
原因可能是因?yàn)榫幾g器認(rèn)為我的變量在函數(shù)內(nèi)部一直是不變吧,于是就把變量從函數(shù)內(nèi)部提出來备燃,傳人函數(shù)內(nèi)部碉克,寫成下面這樣凌唬,就可以編譯通過沒有任何的warning了.
// 當(dāng)然在之前得調(diào)用下這個方法
testEnum(testOne)
// 具體的方法
func testEnum(testOne:TestAssociatedValueEnumerations){
// 為了更加簡潔,也可以下面這樣寫(let 的合理用)
switch testOne{
case let .TestIntType(numberOne, numberTwo):
print("one===\(numberOne),two====\(numberTwo)")
case let .TestStringType(stringTest):
print("string ====\(stringTest)")
}
}
1-2并齐、原始值
枚舉成員可以被默認(rèn)值(稱為原始值)預(yù)填充,這些原始值的類型必須相同客税。
enum TestRawValueString: String {
case TestRawOne = "one"
case TestRawTwo = "Two"
case TestRawThree = "Three"
}
1-3况褪、遞歸枚舉
當(dāng)各種可能的情況可以被窮舉時,非常適合使用枚舉進(jìn)行數(shù)據(jù)建模更耻,例如可以用枚舉來表示用于簡單整數(shù)運(yùn)算的操作符测垛。
可以在枚舉類型開頭加上indirect關(guān)鍵字來表明它的所有成員都是可遞歸的:
indirect enum ArithmeticExpression {
case Number(Int)
case Addition(ArithmeticExpression, ArithmeticExpression)
case Multiplication(ArithmeticExpression, ArithmeticExpression)
}
//具體的計算
override func viewDidLoad() {
super.viewDidLoad()
// 計算 (5 + 4) * 2
let five = ArithmeticExpression.Number(5)
let four = ArithmeticExpression.Number(4)
let sum = ArithmeticExpression.Addition(five, four)
let product = ArithmeticExpression.Multiplication(sum, ArithmeticExpression.Number(2))
print(evaluate(product))
}
func evaluate(expression: ArithmeticExpression) -> Int {
switch expression {
case .Number(let value):
return value
case .Addition(let left, let right):
return evaluate(left) + evaluate(right)
case .Multiplication(let left, let right):
return evaluate(left) * evaluate(right)
}
}
二、類和結(jié)構(gòu)體
類和結(jié)構(gòu)體有著類似的定義方式秧均。我們通過關(guān)鍵字class和struct來分別表示類和結(jié)構(gòu)體食侮,并在一對大括號中定義它們的具體內(nèi)容:
class SomeClass {
// 類
}
struct SomeStructure {
// 結(jié)構(gòu)體
}
具體例子
struct testStructFrame {
var x = 0
var y = 0
}
class testClassForStudent {
var name = "Lucy"
var age = 18
}
//所有結(jié)構(gòu)體都有一個自動生成的成員逐一構(gòu)造器号涯,用于初始化新結(jié)構(gòu)體實(shí)例中成員的屬性。新實(shí)例中各個屬性的初始值可以通過屬性的名稱傳遞到成員逐一構(gòu)造器之中:
let myFrame = testStructFrame(x: 0, y: 0)
//類和結(jié)構(gòu)體的實(shí)例
var ourStruct = testStructFrame()
let ourClass = testClassForStudent()
// 結(jié)構(gòu)體 引用其屬性锯七,這樣的話链快,
ourStruct.y = 100
ourStruct.x = 20
// 類 屬性
ourClass.name = "Yang"
ourClass.age = 24
// 對比 ourStruct 是 var ,而ourClass 是 let
// 推斷出 結(jié)構(gòu)體是值類型,類是引用類型
// 值類型被賦予給一個變量眉尸、常量或者被傳遞給一個函數(shù)的時候域蜗,其值會被拷貝。
// 與值類型不同噪猾,引用類型在被賦予到一個變量霉祸、常量或者被傳遞到一個函數(shù)時,其值不會被拷貝袱蜡。因此丝蹭,引用的是已存在的實(shí)例本身而不是其拷貝。
恒等運(yùn)算符
因?yàn)轭愂且妙愋推阂希锌赡苡卸鄠€常量和變量在幕后同時引用同一個類實(shí)例半夷。(對于結(jié)構(gòu)體和枚舉來說,這并不成立迅细。因?yàn)樗鼈冏鳛橹殿愋臀组希诒毁x予到常量、變量或者傳遞到函數(shù)時茵典,其值總是會被拷貝湘换。)
如果能夠判定兩個常量或者變量是否引用同一個類實(shí)例將會很有幫助。為了達(dá)到這個目的统阿,Swift 內(nèi)建了兩個恒等運(yùn)算符:
等價于(===)
不等價于(!==)
注意 ==
和===
彩倚,也就是“等于”和“等價于”的區(qū)別
“等價于”表示兩個類類型(class type)的常量或者變量引用同一個類實(shí)例。
“等于”表示兩個實(shí)例的值“相等”或“相同”扶平,判定時要遵照設(shè)計者定義的評判標(biāo)準(zhǔn)帆离,因此相對于“相等”來說,這是一種更加合適的叫法结澄。