enum someenumeration
下面是用列舉表示指南針四個方向的例子:
enum compasspoint
列舉中定義的值(如 north,south,east和west)是這個列舉的成員值(或成員)。你可以使用case關鍵字來定義乙個新的列舉成員值。
注意與 c 和 objective-c 不同,swift 的列舉成員在被建立時不會被賦予乙個預設的整型值。在上面的compasspoint例子中,north,south,east和west不會被隱式地賦值為0,1,2和3。相反,這些列舉成員本身就是完備的值,這些值的型別是已經明確定義好的compasspoint型別。
多個成員值可以出現在同一行上,用逗號隔開:
enum planet
var directiontohead =compasspoint.west
directiontohead =.east
當directiontohead的型別已知時,再次為其賦值可以省略列舉型別名。在使用具有顯式型別的列舉值時,這種寫法讓**具有更好的可讀性。
使用 switch 語句匹配列舉值
你可以使用switch語句匹配單個列舉值:
directiontohead = .south
switch directiontohead
// 列印 "watch out for penguins」
正如在控制流中介紹的那樣,在判斷乙個列舉型別的值時,switch語句必須窮舉所有情況。如果忽略了.west這種情況,上面那段**將無法通過編譯,因為它沒有考慮到compasspoint的全部成員。強制窮舉確保了列舉成員不會被意外遺漏。
let someplanet = planet.earth
switch someplanet
// 列印 "mostly harmless」
上一小節的例子演示了如何定義和分類列舉的成員。你可以為planet.earth設定乙個常量或者變數,並在賦值之後檢視這個值。然而,有時候能夠把其他型別的關聯值和成員值一起儲存起來會很有用。這能讓你連同成員值一起儲存額外的自定義資訊,並且你每次在**中使用該列舉成員時,還可以修改這個關聯值。
你可以定義 swift 列舉來儲存任意型別的關聯值,如果需要的話,每個列舉成員的關聯值型別可以各不相同。列舉的這種特性跟其他語言中的可識別聯合(discriminated unions),標籤聯合(tagged unions),或者變體(variants)相似。
然後可以使用任意一種條形碼型別建立新的條形碼,例如:
var productbarcode =barcode.upc(8, 85909, 51226, 3)
上面的例子建立了乙個名為productbarcode的變數,並將barcode.upc賦值給它,關聯的元組值為(8, 85909, 51226, 3)。
同乙個商品可以被分配乙個不同型別的條形碼,例如:
productbarcode = .qrcode("abcdefghijklmnop")
這時,原始的barcode.upc和其整數關聯值被新的barcode.qrcode和其字串關聯值所替代。barcode型別的常量和變數可以儲存乙個.upc或者乙個.qrcode(連同它們的關聯值),但是在同一時間只能儲存這兩個值中的乙個。
像先前那樣,可以使用乙個 switch 語句來檢查不同的條形碼型別。然而,這一次,關聯值可以被提取出來作為 switch 語句的一部分。你可以在switch的 case 分支**中提取每個關聯值作為乙個常量(用let字首)或者作為乙個變數(用var字首)來使用:
switch productbarcode
// 列印 "qr code: abcdefghijklmnop."
如果乙個列舉成員的所有關聯值都被提取為常量,或者都被提取為變數,為了簡潔,你可以只在成員名稱前標註乙個let或者var:
switch productbarcode
// 輸出 "qr code: abcdefghijklmnop."
在關聯值小節的條形碼例子中,演示了如何宣告儲存不同型別關聯值的列舉成員。作為關聯值的替代選擇,列舉成員可以被預設值(稱為原始值)預填充,這些原始值的型別必須相同。
這是乙個使用 ascii 碼作為原始值的列舉:
enum asciicontrolcharacter: character
列舉型別asciicontrolcharacter的原始值型別被定義為character,並設定了一些比較常見的 ascii 控制字元。character的描述詳見字串和字元部分。
原始值可以是字串,字元,或者任意整型值或浮點型值。每個原始值在列舉宣告中必須是唯一的。
注意在使用原始值為整數或者字串型別的列舉時,不需要顯式地為每乙個列舉成員設定原始值,swift 將會自動為你賦值。原始值和關聯值是不同的。原始值是在定義列舉時被預先填充的值,像上述三個 ascii 碼。對於乙個特定的列舉成員,它的原始值始終不變。關聯值是建立乙個基於列舉成員的常量或變數時才設定的值,列舉成員的關聯值可以變化。
例如,當使用整數作為原始值時,隱式賦值的值依次遞增1。如果第乙個列舉成員沒有設定原始值,其原始值將為0。
enum planet: int
當使用字串作為列舉型別的原始值時,每個列舉成員的隱式原始值為該列舉成員的名稱。
enum compasspoint: string
上面例子中,compasspoint.south擁有隱式原始值south,依次類推。
使用列舉成員的rawvalue屬性可以訪問該列舉成員的原始值:
let earthsorder = planet.earth
.rawvalue
// earthsorder 值為 3
let sunsetdirection = compasspoint.west
.rawvalue
// sunsetdirection 值為 "west"
如果在定義列舉型別的時候使用了原始值,那麼將會自動獲得乙個初始化方法,這個方法接收乙個叫做rawvalue的引數,引數型別即為原始值型別,返回值則是列舉成員或nil。你可以使用這個初始化方法來建立乙個新的列舉例項。
這個例子利用原始值7建立了列舉成員uranus:
let possibleplanet = planet(rawvalue: 7)
// possibleplanet 型別為 planet? 值為 planet.uranus
然而,並非所有int值都可以找到乙個匹配的行星。因此,原始值構造器總是返回乙個可選的列舉成員。在上面的例子中,possibleplanet是planet?型別,或者說「可選的planet」。
注意原始值構造器是乙個可失敗構造器,因為並不是每乙個原始值都有與之對應的列舉成員。更多資訊請參見可失敗構造器
如果你試圖尋找乙個位置為11的行星,通過原始值構造器返回的可選planet值將是nil:
let positiontofind = 11
if let someplanet = planet(rawvalue: positiontofind)
} else
// 輸出 "there isn't a planet at position 11
遞迴列舉是一種列舉型別,它有乙個或多個列舉成員使用該列舉型別的例項作為關聯值。使用遞迴列舉時,編譯器會插入乙個間接層。你可以在列舉成員前加上indirect來表示該成員可遞迴。
enum arithmeticexpression
你也可以在列舉型別開頭加上indirect關鍵字來表明它的所有成員都是可遞迴的:
indirect enum arithmeticexpression
let five = arithmeticexpression.number(5)
let four = arithmeticexpression.number(4)
let sum = arithmeticexpression.addition(five, four)
let product = arithmeticexpression.multiplication(sum, arithmeticexpression.number(2))
func evaluate(_ expression: arithmeticexpression) -> int
}print(evaluate(product))// 列印 "18"
Swift學習筆記 10 列舉
1.定義語法 enum someenumeration2.使用 enum compasspoint var directiontohead compasspoint.west directiontohead south switch directiontohead 注 1.變數乙個次賦值為列舉型別以...
swift學習筆記 20 列舉
當乙個變數有固定的幾個取值的時候,建議用列舉,比如說星期,月份等 列舉型別定義的資料型別的取值,只能是 case 後面的取值 enum weekday string var dayone weekday.friday 如果要改變 dayone 的值,用.就可以訪問 dayone monday 如果s...
swift文件筆記 八 列舉
1.列舉語法 enum someenumeration 2.關聯值與原始值 enum asciicontrolcharacter character 如上所示,tab linefeed carriagereturn 是關聯值,表示該列舉的乙個成員。character 是原始值,表示列舉成員的型別。3...