詳解Swift中enum列舉類型的用法。本站提示廣大學習愛好者:(詳解Swift中enum列舉類型的用法)文章只能為提供參考,不一定能成為您想要的結果。以下是詳解Swift中enum列舉類型的用法正文
1、引言
在Objective-C說話中,沒有現實上是整型數據,Swift中的列舉則加倍靈巧,開辟者可以不為其分派值類型把列舉作為自力的類型來應用,也能夠為其分派值,可所以字符,字符串,整型或許浮點型數據。
2、列舉語法
Swift中enum症結字來停止列舉的創立,應用case來創立每個列舉值,示例以下:
//創立姓氏列舉,和Objective-C分歧,Swift列舉不會默許分派值
enum Surname {
case 張
case 王
case 李
case 趙
}
//創立一個列舉類型的變量
var myName = Surname.張
//假如可以主動揣摸出類型 則列舉類型可以省略
myName = .李
var myName2:Surname = .王
異樣可以將列舉值都寫在統一個case中,應用逗號分隔:
enum Planet {
case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}
列舉常常會和Switch語句聯合應用,示例以下:
switch myName {
case .張:
print("姓氏張")
case .王:
print("姓氏王")
case .李:
print("姓氏李")
case .趙:
print("姓氏趙")
}
3、列舉的相干值
Swift中的列舉有一個很成心思的特色,其可以設置一些相干值,經由過程相干值,開辟者可以從公用的列舉值中獲得到傳遞的額定相干值,示例以下:
enum Number {
case one(count:Int)
case two(count:Int)
case three(count:Int)
case four(count:Int)
}
var num = Number.one(count: 5)
switch num {
//獲得num的相干值
case Number.one(let count):
print(count)
default:
print(num)
}
//假如一個列舉值一切的相干中都是常量,let症結字也能夠提取到括號裡面
switch num {
//獲得num的相干值
case let Number.one(count):
print(count)
default:
print(num)
}
有了相干值如許的句法,年夜年夜的增長了列舉的靈巧性,例如一個外形列舉,能夠的列舉值有矩形,圓形等,矩形的列舉值便可以供給寬高的相干值,圓形的列舉值便可以供給半徑的相干值,是開辟加倍靈巧。
4、列舉的原始值
原始值也能夠懂得為為列舉設置一個詳細類型,示例以下:
enum Char:String {
case a = "A"
case b = "B"
case c = "C"
}
//”A“
var char = Char.a.rawValue
留意,假如列舉是Int類型的,則相似於Objective-C,列舉的原始值會從第一個開端以後順次遞增:
enum Char:Int{
case a = 0
case b
case c
}
//1
var char = Char.b.rawValue
異樣可以經由過程原始值的方法來停止列舉對象的創立,示例以下:
enum Char:Int{
case a = 0
case b
case c
}
//1
var char = Char.b.rawValue
//b
var char2 = Char(rawValue:1)
在經由過程原始值停止列舉對象創立的時刻,有能夠創立掉敗,例如傳入的原始值其實不存在,這時候會前往Optional值nil。
4、遞歸列舉
遞歸列舉是Swift列舉中一個難於懂得的處所,現實上也並不是非常難於懂得,開辟者只需明確列舉的本質,遞歸列舉就很好懂得。起首,遞歸是一種算法,可以簡略懂得為本身挪用本身,而列舉現實上其實不是函數,它其實不履行某項運算,它只是表達一個數據或許說他也能夠表達一種表達式,示例以下:
enum Expression {
//表現加
case add
//表現減
case mul
}
後面有提到過相干值的概念,是以,關於上述例子,可認為add和mul列舉值添加兩個相干值作為參數。
enum Expression {
//表現加
case add(Int,Int)
//表現減
case mul(Int,Int)
}
如斯,以下的寫法現實上便可以代表一個5+5的表達式:
var exp = Expression.add(5, 5)
照樣須要強調一點,這個exp只是表達了5+5如許一個商定的表達式,它並沒有真正停止5+5的運算。如今成績就來了,應用如上的列舉,如何來表達相似(5+5)*5如許的復合表達式呢?可使用遞歸列舉來完成,行將(5+5)作為列舉值得相干值再次創立列舉,改革以下:
enum Expression {
//單值數據
case num(Int)
//表現加 indirect為遞歸列舉症結字
indirect case add(Expression,Expression)
//表現減
indirect case mul(Expression,Expression)
}
var exp1 = Expression.num(5)
var exp2 = Expression.num(5)
var exp3 = Expression.add(exp1, exp2)
var exp4 = Expression.mul(exp1, exp3)
下面exp4現實上就表達了(5+5)*5如許一個進程,留意遞歸的列舉值必需加上indirect症結字來聲明。處置遞歸列舉最好的方法是經由過程遞歸函數,示例以下:
func expFunc(param:Expression) -> Int {
//停止列舉斷定
switch param {
//假如是零丁數字 直接前往
case .num(let p):
return p
//假如是加法 則停止遞歸加
case .add(let one, let two):
return expFunc(one)+expFunc(two)
//假如是乘法 則停止遞歸乘
case .mul(let one, let two):
return expFunc(one)*expFunc(two)
}
}
//50
expFunc(exp4)
假如列舉中一切的case都是可遞歸的,可以將全部列舉聲明為可遞歸的:
indirect enum Expression {
//單值數據
case num(Int)
//表現加 indirect為遞歸列舉症結字
case add(Expression,Expression)
//表現減
case mul(Expression,Expression)
}
5、一些重點難點總結
列舉的語法,enum開首,每行成員的界說應用case症結字開首,一行可以界說多個症結字
enum CompassPoint {
case North
case South
case East
case West
}
enum Planet {
case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}
上例中North,South,East,West的值其實不等於0,1,2,3,而是他們自己就是本身的值,且該值的類型就是CompassPoint
var directionToHead = CompassPoint.West //directionToHead是一個CompassPoint類型,可以被賦值為該類型的其他值 //當設置directionToHead的值時,他的類型是已知的,是以可以省略East的類型 directionToHead = .East
應用switch離開列舉的值,以停止的分歧的操作。switch內的case必需包括列舉的一切分支,不然編譯失足。固然,羅列一切列舉值不太便利時,可使用default
directionToHead = .South
switch directionToHead {
case .North:
println("Lots of planets have a north")
case .South:
println("Watch out for penguins")
case .East:
println("Where the sun rises")
case .West:
println("Where the skies are blue")
}
// 打印 "Watch out for penguins"
列舉的元素可所以聯合值(associated value),上面經由過程一個可以存儲一維條形碼(由3個整數構成)和二維條形碼(由字符串構成)的列舉條形碼實例來講明
enum Barcode {
case UPCA(Int, Int, Int)
case QRCode(String)
}
//界說一個變量。該變量便可被賦值為3個整數,又可被賦值為一個字符串,但都是Barcode類型的列舉值
var productBarcode = Barcode.UPCA(8, 85909_51226, 3)
productBarcode = .QRCode("ABCDEFGHIJKLMNOP")
//應用switch時,case內可辨別條形碼品種,可以使用變量或常量取得聯合值
switch productBarcode {
case .UPCA(let numberSystem, let identifier, let check):
println("UPC-A with value of \(numberSystem), \(identifier), \(check).")
case .QRCode(let productCode):
println("QR code with value of \(productCode).")
}
// 打印 "QR code with value of ABCDEFGHIJKLMNOP."
在case外部,假如其類型都為let或var,則該症結字可提早到case和列舉類型中央,如:
case let .UPCA(numberSystem, identifier, check):
原始值類型的列舉在列舉名後緊跟數據類型,其列舉的成員在界說時曾經付與了初始值,且不克不及轉變,與聯合值類型的列舉比擬,聯合值是在將列舉值付與一個變量時,才設置了誰人列舉的值。
原始值列舉更像C說話的列舉,好比整數型的原始值列舉,其成員的值假如未指定,則是遞增的。
原始值列舉也像字典類型,而且是雙向字典,由於他既可以經由過程列舉成員取得該成員原始值,又可以經由過程原始值,取得列舉成員。由此也能夠見得,這類列舉的原始值是不克不及湧現雷同值的
//原始值列舉的類型緊跟列舉名後,其成員的原始值的數據類型都是這個指定的類型
enum ASCIIControlCharacter: Character {
case Tab = "\t"
case LineFeed = "\n"
case CarriageReturn = "\r"
}
//Int類型的原始值列舉成員的原始值是遞增的,好比Venus的值是2,Earth的值是3
enum Planet: Int {
case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}
//可以經由過程toRaw辦法取得列舉成員的原始值
let earthsOrder = Planet.Earth.toRaw()
// earthsOrder 的值是 3,數據類型是Int
//可以經由過程fromRaw辦法取得原始值對應的列舉成員
let possiblePlanet = Planet.fromRaw(7)
// possiblePlanet 的數據類型 Planet? 值是 Planet.Uranus
//由於fromRaw的原始值能夠沒有對應的列舉成員,所以前往的類型是一個可選變量值
let positionToFind = 9
if let somePlanet = Planet.fromRaw(positionToFind) {
switch somePlanet {
case .Earth:
println("Mostly harmless")
default:
println("Not a safe place for humans")
}
} else {
println("There isn't a planet at position \(positionToFind)")
}
// 列舉界說中沒有原始值為9的成員,所以打印 "There isn't a planet at position 9"