一個簡單的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通過協議和操作符定義, 讓我們的代碼更加美妙.