Swift教程之枚舉類(lèi)型詳解
枚舉定義了一個(gè)常用的具有相關(guān)性的一組數(shù)據(jù),并在你的代碼中以一個(gè)安全的方式使用它們。
如果你熟悉C語(yǔ)言,你就會(huì)知道,C語(yǔ)言中的枚舉指定相關(guān)名稱(chēng)為一組整數(shù)值。在Swift中枚舉更為靈活,不必為枚舉的每個(gè)成員提供一個(gè)值。如果一個(gè)值(被稱(chēng)為“原始”的值)被提供給每個(gè)枚舉成員,則該值可以是一個(gè)字符串,一個(gè)字符,或者任何整數(shù)或浮點(diǎn)類(lèi)型的值。
另外,枚舉成員可以指定任何類(lèi)型,每個(gè)成員都可以存儲(chǔ)的不同的相關(guān)值,就像其他語(yǔ)言中使用集合或變體。你還可以定義一組通用的相關(guān)成員為一個(gè)枚舉,每一種都有不同的一組與它相關(guān)的適當(dāng)類(lèi)型的值的一部分。
在Swift中枚舉類(lèi)型是最重要的類(lèi)型。它采用了很多以前只有類(lèi)才具有的特性,如計(jì)算性能,以提供有關(guān)枚舉的當(dāng)前值的更多信息,方法和實(shí)例方法提供的功能相關(guān)的枚舉表示的值傳統(tǒng)上支持的許多功能。枚舉也可以定義初始化,以提供一個(gè)初始成員值;可以在原有基礎(chǔ)上擴(kuò)展擴(kuò)大它們的功能;并使用協(xié)議來(lái)提供標(biāo)準(zhǔn)功能。
欲了解更多有關(guān)這些功能,請(qǐng)參見(jiàn)Properties, Methods, Initialization, Extensions, Protocols
1、枚舉語(yǔ)法
使用枚舉enum關(guān)鍵詞并把他們的整個(gè)定義在一對(duì)大括號(hào)內(nèi):
enum SomeEnumeration {
// enumeration definition goes here
}
下面是一個(gè)指南針的四個(gè)點(diǎn)一個(gè)例子:
enum CompassPoint {
case North
case South
case East
case West
}
在枚舉中定義的值(如North,South,East和West)是枚舉的成員值(或成員)。這個(gè)例子里case關(guān)鍵字表示成員值一條新的分支將被定義。
Note
不像C和Objective-C,Swift枚舉成員在創(chuàng)建時(shí)不分配默認(rèn)整數(shù)值。在上面的例子CompassPoints中North,South,Eath,West不等于隱含0,1,2和3,而是一種與CompassPoint明確被定義的類(lèi)型卻各不相同的值。
多個(gè)成員的值可以出現(xiàn)在一行上,用逗號(hào)分隔:
enum Planet {
case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}
每個(gè)枚舉定義中定義了一個(gè)全新的類(lèi)型。像其他Swift的類(lèi)型,它們的名稱(chēng)(如CompassPoint和Planet)應(yīng)為大寫(xiě)字母。給枚舉類(lèi)型單數(shù)而不是復(fù)數(shù)的名字,這樣理解起來(lái)更加容易如:
var directionToHead = CompassPoint.West
使用directionToHead的類(lèi)型時(shí),用CompassPoint的一個(gè)可能值初始化的推斷。一旦directionToHead被聲明為一個(gè)CompassPoint,您可以將其設(shè)置為使用更短的.語(yǔ)法而不用再書(shū)寫(xiě)枚舉CompassPoint值本身:
directionToHead = .East
directionToHead的類(lèi)型是已知的,所以你可以在設(shè)定它的值時(shí),不寫(xiě)該類(lèi)型。使用類(lèi)型明確的枚舉值可以讓代碼具有更好的可讀性。
2、匹配枚舉值與switch語(yǔ)句
你可以使用單個(gè)枚舉值匹配switch語(yǔ)句:
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的價(jià)值。當(dāng)它等于North,打印“Lots of planets have a north”。當(dāng)它等于South,打印“Watch out for penguins”等等。
正如控制流所描述,Switch語(yǔ)句考慮枚舉的成員,如果省略了West時(shí),這段代碼無(wú)法編譯,因?yàn)樗鼪](méi)有考慮CompassPoint成員的完整性。Switch語(yǔ)句要求全面性確保枚舉成員,避免不小心漏掉情況發(fā)生。
當(dāng)它不需要為每一個(gè)枚舉成員都匹配的情況下,你可以提供一個(gè)默認(rèn)default分支來(lái)涵蓋未明確提到的任何成員:
let somePlanet = Planet.Earth
switch somePlanet {
case .Earth:
println("Mostly harmless")
default:
println("Not a safe place for humans")
}
// prints "Mostly harmless"
3、關(guān)聯(lián)值
在上一節(jié)中的示例延時(shí)了一個(gè)枚舉的成員是如何被定義(分類(lèi))的。你可以為Planet.Earth設(shè)置一個(gè)常量或變量,然后在代碼中檢查這個(gè)值。但是,它有時(shí)是有用的才能存儲(chǔ)其它類(lèi)型的關(guān)聯(lián)值除了這些成員的值。這讓你隨著成員值存儲(chǔ)額外的自定義信息,并允許在你的代碼中來(lái)使用該信息。
Swift的枚舉類(lèi)型可以由一些數(shù)據(jù)類(lèi)型相關(guān)的組成,如果需要的話,這些數(shù)據(jù)類(lèi)型可以是各不相同的。枚舉的這種特性跟其它語(yǔ)言中的奇異集合,標(biāo)簽集合或者變體相似
例如,假設(shè)一個(gè)庫(kù)存跟蹤系統(tǒng)需要由兩種不同類(lèi)型的條形碼來(lái)跟蹤產(chǎn)品。有些產(chǎn)品上標(biāo)有UPC-A代碼格式,它使用數(shù)字0到9的一維條碼,每一個(gè)條碼都有一個(gè)“數(shù)字系統(tǒng)”的數(shù)字,后跟十“標(biāo)識(shí)符”的數(shù)字。最后一位是“檢查”位,以驗(yàn)證代碼已被正確掃描:
其他產(chǎn)品都貼有二維條碼QR碼格式,它可以使用任何的ISO8859-1字符,并可以編碼字符串,最多2,953個(gè)字符:
這將是方便的庫(kù)存跟蹤系統(tǒng)能夠存儲(chǔ)UPC-A條碼作為三個(gè)整數(shù)的元組,和QR代碼的條形碼的任何長(zhǎng)度的字符串。
在Swift中可以使用一個(gè)枚舉來(lái)定義兩種類(lèi)型的產(chǎn)品條形碼,結(jié)構(gòu)可以是這樣的:
enum Barcode {
case UPCA(Int, Int, Int)
case QRCode(String)
}
這可以被理解為:
“定義一個(gè)名為條形碼枚舉類(lèi)型,它可以是UPC-A的任一值類(lèi)型的關(guān)聯(lián)值(Int,Int,Int),或QRCode的一個(gè)類(lèi)型為String的關(guān)聯(lián)值?!?/p>
這個(gè)定義不提供任何實(shí)際的Int或String值,它只是定義了條形碼常量和變量當(dāng)?shù)扔贐arcode.UPCA或Barcode.QRCode關(guān)聯(lián)值的類(lèi)型的時(shí)候的存儲(chǔ)形式。
然后可以使用任何一種類(lèi)型來(lái)創(chuàng)建新的條碼:
var productBarcode = Barcode.UPCA(8, 85909_51226, 3)
此示例創(chuàng)建一個(gè)名為productBarcode新的變量,并與相關(guān)聯(lián)的元組值賦給它Barcode.UPCA的值(8,8590951226,3)。提供的“標(biāo)識(shí)符”值都有整數(shù)加下劃線的文字,85909_51226,使其更易于閱讀的條形碼。
同一產(chǎn)品可以分配不同類(lèi)型的條形碼:
productBarcode = .QRCode("ABCDEFGHIJKLMNOP")
在這一點(diǎn)上,原來(lái)Barcode.UPCA和其整數(shù)值被新的Barcode.QRCode及其字符串值代替。_條形碼的常量和變量可以存儲(chǔ)任何一個(gè)_UPCA或QRCode的(連同其關(guān)聯(lián)值),但它們只能存儲(chǔ)其中之一在任何指定時(shí)間。
不同的條碼類(lèi)型像以前一樣可以使用一個(gè)switch語(yǔ)句來(lái)檢查,但是這一次相關(guān)的值可以被提取作為switch語(yǔ)句的一部分。您提取每個(gè)相關(guān)值作為常數(shù)(let前綴)或變量(var前綴)不同的情況下,在switch語(yǔ)句的case代碼內(nèi)使用:
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."
如果所有的枚舉成員的關(guān)聯(lián)值的提取為常數(shù),或者當(dāng)所有被提取為變量,為了簡(jiǎn)潔起見(jiàn),可以放置一個(gè)var,或let標(biāo)注在成員名稱(chēng)前:
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、原始值
在關(guān)聯(lián)值的條形碼的例子演示了一個(gè)枚舉的成員如何能聲明它們存儲(chǔ)不同類(lèi)型的關(guān)聯(lián)值。作為替代關(guān)聯(lián)值,枚舉成員可以拿出預(yù)先填入缺省值(稱(chēng)為原始值),從而具有相同的類(lèi)型。
這里是一個(gè)存儲(chǔ)原始的ASCII值命名枚舉成員的一個(gè)例子:
enum ASCIIControlCharacter: Character {
case Tab = "\t"
case LineFeed = "\n"
case CarriageReturn = "\r"
}
在這里,原始值被定義為字符類(lèi)型的枚舉叫做ASCIIControlCharacter,并設(shè)置了一些比較常見(jiàn)的ASCII控制字符。字符值的字符串和字符的描述。
注意,原始值是不相同關(guān)聯(lián)值。原始值設(shè)置為預(yù)填充的值時(shí),應(yīng)先在你的代碼中定義枚舉,像上述三個(gè)ASCII碼。對(duì)于一個(gè)特定的枚舉成員的原始值始終是相同的。當(dāng)你創(chuàng)建一個(gè)基于枚舉的常量或變量的新成員的關(guān)聯(lián)值設(shè)置,每次當(dāng)你這樣做的時(shí)候可以是不同的。
原始值可以是字符串,字符,或任何整數(shù)或浮點(diǎn)數(shù)類(lèi)型。每個(gè)原始值必須在它的枚舉中唯一聲明。當(dāng)整數(shù)被用于原始值,如果其他枚舉成員沒(méi)有值時(shí),它們自動(dòng)遞增。
下面列舉的是一個(gè)細(xì)化的早期Planet枚舉,使用原始整數(shù)值來(lái)表示每個(gè)Planet的太陽(yáng)系的順序:
enum Planet: Int {
case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}
自動(dòng)遞增意味著Planet.Venus具有2的原始值,依此類(lèi)推。
訪問(wèn)其toRaw方法枚舉成員的原始值:
let earthsOrder = Planet.Earth.toRaw()
// earthsOrder is 3
使用枚舉的fromRaw方法來(lái)試圖找到一個(gè)特定的原始值枚舉成員。這個(gè)例子識(shí)別Uranus的位置通過(guò)原始值為7:
let possiblePlanet = Planet.fromRaw(7)
// possiblePlanet is of type Planet? and equals Planet.Uranus
然而,并非所有可能的Int值都會(huì)找到一個(gè)匹配的星球。正因如此,該fromRaw方法返回一個(gè)可選的枚舉成員。在上面的例子中,是possiblePlanet類(lèi)型Planet?或“可選的Planet”。
如果你試圖找到一個(gè)Planet為9的位置,通過(guò)fromRaw返回可選的Planet值將是無(wú):
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"
這個(gè)范例使用somePlanet= Planet.fromRaw(9)來(lái)嘗試訪問(wèn)可選集合Planet,在可選Planet集合中設(shè)置檢索條件somePlanet,在原始值為9的情況下,不能檢索到位置為9的星球,所有else分支被執(zhí)行。
相關(guān)文章
swift4 使用DrawerController實(shí)現(xiàn)側(cè)滑菜單功能的示例代碼
這篇文章主要介紹了swift4 使用DrawerController實(shí)現(xiàn)側(cè)滑功能的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-06-06swift 3.0 正則表達(dá)式查找/替換字符的實(shí)現(xiàn)代碼
正則表達(dá)式使用單個(gè)字符串來(lái)描述、匹配一系列符合某個(gè)句法規(guī)則的字符串。本文重點(diǎn)給大家介紹swift 3.0 正則表達(dá)式查找/替換字符的實(shí)現(xiàn)代碼,需要的朋友參考下吧2017-08-08Swift Access Control訪問(wèn)控制與斷言詳細(xì)介紹
這篇文章主要介紹了Swift Access Control訪問(wèn)控制與斷言,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-09-09Swift Extension擴(kuò)展得使用詳細(xì)介紹
在swift中,extension與Objective-C的category有點(diǎn)類(lèi)似,但是extension比起category來(lái)說(shuō)更加強(qiáng)大和靈活,它不僅可以擴(kuò)展某種類(lèi)型或結(jié)構(gòu)體的方法,同時(shí)它還可以與protocol等結(jié)合使用,編寫(xiě)出更加靈活和強(qiáng)大的代碼2022-09-09Swift利用CoreData如何存儲(chǔ)多種數(shù)據(jù)類(lèi)的通訊錄
這篇文章主要給大家介紹了關(guān)于Swift利用CoreData如何存儲(chǔ)多種數(shù)據(jù)類(lèi)的通訊錄的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-12-12