Swift教程之列舉類型詳解。本站提示廣大學習愛好者:(Swift教程之列舉類型詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是Swift教程之列舉類型詳解正文
列舉界說了一個經常使用的具有相干性的一組數據,並在你的代碼中以一個平安的方法應用它們。
假如你熟習C說話,你就會曉得,C說話中的列舉指定相干稱號為一組整數值。在Swift中列舉更加靈巧,不用為列舉的每一個成員供給一個值。假如一個值(被稱為“原始”的值)被供給給每一個列舉成員,則該值可所以一個字符串,一個字符,或許任何整數或浮點類型的值。
別的,列舉成員可以指定任何類型,每一個成員都可以存儲的分歧的相干值,就像其他說話中應用聚集或變體。你還可以界說一組通用的相干成員為一個列舉,每種都有分歧的一組與它相干的恰當類型的值的一部門。
在Swift中列舉類型是最主要的類型。它采取了許多之前只要類才具有的特征,如盤算機能,以供給有關列舉確當前值的更多信息,辦法和實例辦法供給的功效相干的列舉表現的值傳統上支撐的很多功效。列舉也能夠界說初始化,以供給一個初始成員值;可以在原有基本上擴大擴展它們的功效;並應用協定來供給尺度功效。
欲懂得更多有關這些功效,請拜見Properties, Methods, Initialization, Extensions, Protocols
1、列舉語法
應用列舉enum症結詞並把他們的全部界說在一對年夜括號內:
enum SomeEnumeration {
// enumeration definition goes here
}
上面是一個指南針的四個點一個例子:
enum CompassPoint {
case North
case South
case East
case West
}
在列舉中界說的值(如North,South,East和West)是列舉的成員值(或成員)。這個例子裡case症結字表現成員值一條新的分支將被界說。
Note
不像C和Objective-C,Swift列舉成員在創立時不分派默許整數值。在下面的例子CompassPoints中North,South,Eath,West不等於隱含0,1,2和3,而是一種與CompassPoint明白被界說的類型卻各不雷同的值。
多個成員的值可以湧現在一行上,用逗號分隔:
enum Planet {
case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}
每一個列舉界說中界說了一個全新的類型。像其他Swift的類型,它們的稱號(如CompassPoint和Planet)應為年夜寫字母。給列舉類型雙數而不是單數的名字,如許懂得起來加倍輕易如:
var directionToHead = CompassPoint.West
應用directionToHead的類型時,用CompassPoint的一個能夠值初始化的揣摸。一旦directionToHead被聲明為一個CompassPoint,您可以將其設置為應用更短的.語法而不消再書寫列舉CompassPoint值自己:
directionToHead = .East
directionToHead的類型是已知的,所以你可以在設定它的值時,不寫該類型。應用類型明白的列舉值可讓代碼具有更好的可讀性。
2、婚配列舉值與switch語句
你可使用單個列舉值婚配switch語句:
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")
}
// prints "Watch out for penguins"
你可以懂得這段代碼:
“斟酌directionToHead的價值。當它等於North,打印“Lots of planets have a north”。當它等於South,打印“Watch out for penguins”等等。
正如掌握流所描寫,Switch語句斟酌列舉的成員,假如省略了West時,這段代碼沒法編譯,由於它沒有斟酌CompassPoint成員的完全性。Switch語句請求周全性確保列舉成員,防止不當心漏失落情形產生。
當它不須要為每個列舉成員都婚配的情形下,你可以供給一個默許default分支來涵蓋未明白提到的任何成員:
let somePlanet = Planet.Earth
switch somePlanet {
case .Earth:
println("Mostly harmless")
default:
println("Not a safe place for humans")
}
// prints "Mostly harmless"
3、聯系關系值
在上一節中的示例延時了一個列舉的成員是若何被界說(分類)的。你可認為Planet.Earth設置一個常量或變量,然後在代碼中檢討這個值。然則,它有時是有效的能力存儲其它類型的聯系關系值除這些成員的值。這讓你跟著成員值存儲額定的自界說信息,並許可在你的代碼中來應用該信息。
Swift的列舉類型可以由一些數據類型相干的構成,假如須要的話,這些數據類型可所以各不雷同的。列舉的這類特征跟其它說話中的奇怪聚集,標簽聚集或許變體類似
例如,假定一個庫存跟蹤體系須要由兩種分歧類型的條形碼來跟蹤產物。有些產物上標有UPC-A代碼格局,它應用數字0到9的一維條碼,每個條碼都有一個“數字體系”的數字,後跟十“標識符”的數字。最初一名是“檢討”位,以驗證代碼已被准確掃描:
其他產物都貼有二維條碼QR碼格局,它可使用任何的ISO8859-1字符,並可以編碼字符串,最多2,953個字符:
這將是便利的庫存跟蹤體系可以或許存儲UPC-A條碼作為三個整數的元組,和QR代碼的條形碼的任何長度的字符串。
在Swift中可使用一個列舉來界說兩品種型的產物條形碼,構造可所以如許的:
enum Barcode {
case UPCA(Int, Int, Int)
case QRCode(String)
}
這可以被懂得為:
“界說一個名為條形碼列舉類型,它可所以UPC-A的任一值類型的聯系關系值(Int,Int,Int),或QRCode的一個類型為String的聯系關系值。”
這個界說不供給任何現實的Int或String值,它只是界說了條形碼常量和變量當等於Barcode.UPCA或Barcode.QRCode聯系關系值的類型的時刻的存儲情勢。
然後可使用任何一品種型來創立新的條碼:
var productBarcode = Barcode.UPCA(8, 85909_51226, 3)
此示例創立一個名為productBarcode新的變量,並與相干聯的元組值賦給它Barcode.UPCA的值(8,8590951226,3)。供給的“標識符”值都有整數加下劃線的文字,85909_51226,使其更容易於浏覽的條形碼。
統一產物可以分派分歧類型的條形碼:
productBarcode = .QRCode("ABCDEFGHIJKLMNOP")
在這一點上,本來Barcode.UPCA和其整數值被新的Barcode.QRCode及其字符串值取代。_條形碼的常量和變量可以存儲任何一個_UPCA或QRCode的(連同其聯系關系值),但它們只能存儲個中之一在任何指准時間。
分歧的條碼類型像之前一樣可使用一個switch語句來檢討,然則這一次相干的值可以被提取作為switch語句的一部門。您提取每一個相干值作為常數(let前綴)或變量(var前綴)分歧的情形下,在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).")
}
// prints "QR code with value of ABCDEFGHIJKLMNOP."
假如一切的列舉成員的聯系關系值的提取為常數,或許當一切被提取為變量,為了簡練起見,可以放置一個var,或let標注在成員稱號前:
switch productBarcode {
case let .UPCA(numberSystem, identifier, check):
println("UPC-A with value of \(numberSystem), \(identifier), \(check).")
case let .QRCode(productCode):
println("QR code with value of \(productCode).")
}
// prints "QR code with value of ABCDEFGHIJKLMNOP."
4、原始值
在聯系關系值的條形碼的例子演示了一個列舉的成員若何能聲明它們存儲分歧類型的聯系關系值。作為替換聯系關系值,列舉成員可以拿出事後填入缺省值(稱為原始值),從而具有雷同的類型。
這裡是一個存儲原始的ASCII值定名列舉成員的一個例子:
enum ASCIIControlCharacter: Character {
case Tab = "\t"
case LineFeed = "\n"
case CarriageReturn = "\r"
}
在這裡,原始值被界說為字符類型的列舉叫做ASCIIControlCharacter,並設置了一些比擬罕見的ASCII掌握字符。字符值的字符串和字符的描寫。
留意,原始值是不雷同聯系關系值。原始值設置為預填充的值時,應先在你的代碼中界說列舉,像上述三個ASCII碼。關於一個特定的列舉成員的原始值一直是雷同的。當你創立一個基於列舉的常量或變量的新成員的聯系關系值設置,每次當你如許做的時刻可所以分歧的。
原始值可所以字符串,字符,或任何整數或浮點數類型。每一個原始值必需在它的列舉中獨一聲明。當整數被用於原始值,假如其他列舉成員沒有值時,它們主動遞增。
上面羅列的是一個細化的晚期Planet列舉,應用原始整數值來表現每一個Planet的太陽系的次序:
enum Planet: Int {
case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}
主動遞增意味著Planet.Venus具有2的原始值,依此類推。
拜訪其toRaw辦法列舉成員的原始值:
let earthsOrder = Planet.Earth.toRaw()
// earthsOrder is 3
應用列舉的fromRaw辦法來試圖找到一個特定的原始值列舉成員。這個例子辨認Uranus的地位經由過程原始值為7:
let possiblePlanet = Planet.fromRaw(7)
// possiblePlanet is of type Planet? and equals Planet.Uranus
但是,並不是一切能夠的Int值都邑找到一個婚配的星球。正因如斯,該fromRaw辦法前往一個可選的列舉成員。在下面的例子中,是possiblePlanet類型Planet?或“可選的Planet”。
假如你試圖找到一個Planet為9的地位,經由過程fromRaw前往可選的Planet值將是無:
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)")
}
// prints "There isn't a planet at position 9"
這個典范應用somePlanet= Planet.fromRaw(9)來測驗考試拜訪可全集合Planet,在可選Planet聚集中設置檢索前提somePlanet,在原始值為9的情形下,不克不及檢索到地位為9的星球,一切else分支被履行。