一個簡單的Bool類型內部就包含了許多Swift主要功能, 如何構建一個簡單類型是有趣的演示. 本文將創建一個與Bool類型在設計與實現上非常相似的新MyBool類型.我們希望通過設計和實現一個簡單的Swift類型能讓你更好的理解Swift語言是如何工作的.
enum MyBool { case myTrue, myFalse }
讓我們從基本的定義開始. MyBool類型有兩種不同狀態, 用enum來實現
extension MyBool { init() { self = .myFalse } }
為了不誤解,我們命名狀態為 myTrue 和 myFalse. 我們希望 MyBool() 默認為false值, 因此我們實現一個 init 方法:
Swift enum 聲明隱含了枚舉值的有效范圍, 它允許我們使用 MyBool.myFalse 甚至是在環境類型允許時可以使用 .myFalse. 然而, 我們需要我們的類型可以用 true 和 false 常量賦值. 要實現它, 我們讓 MyBool 實現 BooleanLiteralConvertible 協議:
extension MyBool : BooleanLiteralConvertible {
extension MyBool : BooleanLiteralConvertible { static func convertFromBooleanLiteral(value: Bool) -> MyBool { return value ? myTrue : myFalse } } //就樣,我們就可以把'true'和'false'賦給MyBool var a : MyBool = true
這一步完成, 我們就有了基礎類型, 但是我們做的事情還不夠. Booleans 需要用於 if 條件判斷. Swift用 BooleanType 協議來實現它, 它使任意類型都可以用於邏輯條件:
extension MyBool : BooleanType { var boolValue: Bool { switch self { case .myTrue: return true case .myFalse: return false } } } // 現在MyBool可以用於 'if' 各 'while' 條件判斷. if a {}
我們同樣希望所以符合 BooleanType 協議的變量可以轉換到MyBool, 所以我們加上
extension MyBool { // MyBool可以通過BooleanType構造 init(_ v : BooleanType) { if v.boolValue { self = .myTrue } else { self = .myFalse } } } // 現在可以將 boolean-like 類型. var basicBool : Bool = true a = MyBool(basicBool)
注意, 在初始化參數中使用 _ 來禁用參數關鍵字, 它允許使用 MyBool(x) 語法來替代默認的 MyBool(v: x).
現在我們有了基本的功能, 下面我們從 == 開始定義一些操作符. 編譯器並沒有使簡單的枚舉自動 Equatable, 因此還需要額外的代碼. 這裡, 你可以實現 Equatable 協議和 == 操作符來實現任意類型進行相等比較. 如果 MyBool還沒有 Equatable, 可以實現如下:
extension MyBool : Equatable { } func ==(lhs: MyBool, rhs: MyBool) -> Bool { switch (lhs, rhs) { case (.myTrue,.myTrue), (.myFalse,.myFalse): return true default: return false } } // 現在可以用 == 和 != 比較 if a == a {} if a != a {}
這裡我們在switch語句中用一些簡單的模式匹配來處理. 既然 MyBool 已經 Equatable, 我們就不用再實現 != 操作符. 下面我們加入二進制操作:
func &(lhs: MyBool, rhs: MyBool) -> MyBool { if lhs { return rhs } return false } func |(lhs: MyBool, rhs: MyBool) -> MyBool { if lhs { return true } return rhs } func ^(lhs: MyBool, rhs: MyBool) -> MyBool { return MyBool(lhs != rhs) }
使用基本的操作符, 我們可以實現其它有用的一元和組合賦值符, 例如:
prefix func !(a: MyBool) -> MyBool { return a ^ true } // 組合賦值 func &=(inout lhs: MyBool, rhs: MyBool) { lhs = lhs & rhs }
在 &= 操作符中, 因為左值需要修改值, 我們為參數加上 inout 修飾符. 對值類型(如enum和struct), Swift為你提供了完整的修改操作控制.
通過這些, 簡單 MyBool 類型有了所有的基本操作和操作符. 希望本文的提示可以為定義高級類型提供參考.
來自:蘋果官方博客2014-8-5 Boolean
麻雀雖小, 五髒俱全. Swift通過協議和操作符定義, 讓我們的代碼更加美妙.