Enumerations
Raw Values
在 Swift 中也可以定義跟 c 語言很像的 enumerations,我們定義有 raw value 的 enumeration 如下:
enum Planet: Int {
case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}
我們可以得到 enum 的 raw value:
let earthNumber = Planet.Earth.toRaw()
// earthNumber is 3
其中 toRaw()
是 keyword,會回傳 raw value。
當然不只這樣,Swift 中還可以給 enum 不同的型態的 raw value:
enum ControlCharacter: Character {
case Tab = "\t"
case Linefeed = "\n"
case CarriageReturn = "\r"
}
let characterType = ControlCharacter.Tab.toRaw()
// characterType is '"\t"'
Without Raw Value
但是有時候 raw value 根本用不到,我們只想要有不一樣的 enum properties,能夠分類就好,因此我們根本不用定義 raw value:
enum CompassPoint {
case North, South, East, West
}
在這個例子中,North
就是 raw value 本身,因此 Swift 會自動幫你推斷出這個 enum 沒有 raw value,因此也沒有 .toRaw()
可以呼叫。
另外在 Swift 中,還有一個更方便的地方,利用 Type Inference 可以更簡單的操作 enum:
enum CompassPoint {
case North, South, East, West
}
var directionToHead = CompassPoint.West
// directionToHead is inferred to be a CompassPoint
directionToHead = .East
以上的範例中,Swift 幫你推論出 directionToHead
的型態為 CompassPoint
。因此,如果要改變 directionToHead
的內容,只要加上 .East
就可以了,不用再寫成 CompassPoint.East
,超級方便的!
這有什麼好處呢?這個功能在開發 iOS 程式時超方便,看一下範例就知道:
let label = UILabel()
label.textAlignment = .Right
我們想要改變 label
的 textAlignment
,不用知道 textAlignment
的型態是什麼,只要用 .
就會跑出 enum 的選項讓我選擇,真是方便太多啦!
Associated Values
Swift 中 enum 可以做的事情更多,我們可以給 enum 一個相關的參數 (Associated Values)。
假設我們要設計一個 火車狀態查詢 App,火車有兩個狀態:1. OneTime
,2. Delayed
,此時我們的 enum 如下:
enum TrainStatus {
case OnTime
case Delayed(Int)
}
這表示,當我們要設定 Delayed
時,可以給一個 Int
的參數:
enum TrainStatus {
case OnTime
case Delayed(Int)
}
var status = TrainStatus.OnTime
// status is inferred to be a TrainStatus
status = .Delayed(42)
要如何使用這個 Delayed(42)
的參數呢?
Enumerations: Initializers And Properties
Swift 中的 enum 也可以定義 initializers 與 properties,我們定義 description
,輸出目前火車的狀態:
enum TrainStatus {
case OnTime, Delayed(Int)
init() {
self = OnTime
}
var description: String {
switch self {
case OnTime:
return "on time"
case Delayed(let minutes):
return "delayed by \(minutes) minute(s)"
}
}
}
其中,我們在 description()
這個 method,使用到 Delayed
的 associated values。這就是 Swift 中 enum 強大的地方。
最後,我們可以呼叫 description()
,就可以得到 delayed 多久了:
var status = TrainStatus()
println("The train is \(status.description)")
// The train is on time
status = .Delayed(42)
println("The train is now \(status.description)")
// The train is now delayed by 42 minute(s)
Nested Types
Swift 的 enum 不一定要獨立定義,可以定義在其他 class 中,可以有 nested types:
class Train {
enum Status {
case OnTime, Delayed(Int)
init() {
self = OnTime
}
var description: String { ... }
}
var status = Status()
}
這麼一來,Status
就包在 Train
裡面,當 Train
被其他人繼承時也一併包含了 Status
,讓開發者在開發時更方便了!
下一篇: Extensions