Swift中的Bool類(lèi)型是許多原始函數(shù)的基礎(chǔ)。所以基于它可以展示一個(gè)有趣的如何構(gòu)建基本類(lèi)型的示例。這篇文章的主旨是在Swift中創(chuàng)建一個(gè)類(lèi)似Bool類(lèi)型的新類(lèi)型MyBool。我們希望通過(guò)這個(gè)簡(jiǎn)單的示例,能讓你更清晰的了解Swift語(yǔ)言的工作原理。
讓我們從最基本的定義開(kāi)始。我們用枚舉來(lái)定義MyBool
類(lèi)型的模型,它有兩個(gè)不同的case
:
enum MyBool {
case myTrue, myFalse
}
為了使大家不會(huì)產(chǎn)生混淆,這篇文章中我們將MyBool
的兩個(gè)case
命名為myTrue
和myFalse
。我們希望MyBool的構(gòu)造函數(shù)MyBool()
將其自身賦值為false
,所以我們提供了如下init方法:
extension MyBool {
init() { self = .myFalse }
}
Swift中的枚舉會(huì)隱式的在它們自身內(nèi)申明其枚舉檢索器的范圍,允許我們使用MyBool.myFalse
這種語(yǔ)法調(diào)用其成員,如果根據(jù)上下文可以推斷出類(lèi)型的話(huà),我們甚至可以使用.myFalse
調(diào)用其成員。但是在真正使用中,我們還是希望使用原始的true
和false
關(guān)鍵字。想要做到這一點(diǎn),我們的新類(lèi)型MyBool
需要遵循BooleanLiteralConvertible
協(xié)議,像這樣:
extension MyBool : BooleanLiteralConvertible {
static func convertFromBooleanLiteral(value: Bool) -> MyBool {
return value ? myTrue : myFalse
}
}
// 我們現(xiàn)在就可以給MyBool類(lèi)型的變量賦值為true或false.
var a : MyBool = true
通過(guò)以上設(shè)置,我們有了自己的基本類(lèi)型,但是目前我們用它還做不了什么。布爾值需要通過(guò)if條件語(yǔ)句進(jìn)行測(cè)試。在Swift中,我們通過(guò)BooleanType
協(xié)議來(lái)做到這一點(diǎn),該協(xié)議允許任意類(lèi)型用于進(jìn)行邏輯判斷:
extension MyBool : BooleanType {
func getBooleanType() -> Bool {
switch self {
case .myTrue: return true
case .myFalse: return false
}
}
}
// 現(xiàn)在我們就可以將MyBool類(lèi)型的變量a用于'if'和'while'語(yǔ)句中進(jìn)行測(cè)試.
if a {}
我們更希望所有遵循了BooleanType協(xié)議的類(lèi)型都要強(qiáng)制轉(zhuǎn)換為MyBool類(lèi)型,所以我們可以這樣寫(xiě):
extension MyBool {
// MyBool類(lèi)型構(gòu)造函數(shù)的參數(shù)設(shè)定為BooleanType類(lèi)型.
init(_ v : BooleanType) {
if v.getBooleanType() {
self = .myTrue
} else {
self = .myFalse
}
}
}
// 現(xiàn)在我們就可以這樣進(jìn)行轉(zhuǎn)換了.
var basicBool : Bool = true
a = MyBool(basicBool)
注意構(gòu)造函數(shù)里的_
,它可以使我們?cè)谑褂脴?gòu)造函數(shù)時(shí)省略參數(shù)命名。可以使用MyBool(x)
這種語(yǔ)法,而不用使用MyBool(v: x)
這種啰嗦的語(yǔ)法。
現(xiàn)在我們有了基本的功能,現(xiàn)在讓我們來(lái)定義它的操作符,先來(lái)看看如何定義==
操作符。沒(méi)有關(guān)聯(lián)數(shù)據(jù)的簡(jiǎn)單的枚舉(像MyBool一樣)是由編譯器自動(dòng)認(rèn)為遵循Equatable協(xié)議進(jìn)行編譯的,所以沒(méi)有必須要實(shí)現(xiàn)額外的代碼。盡管如此,你也可以讓任意類(lèi)型遵循Equatable
協(xié)議,并實(shí)現(xiàn)==
操作符。比如我們的MyBool
類(lèi)型:
extension MyBool : Equatable {
}
func ==(lhs: MyBool, rhs: MyBool) -> Bool {
switch (lhs, rhs) {
case (.myTrue,.myTrue), (.myFalse,.myFalse):
return true
default:
return false
}
}
// 現(xiàn)在我們就可以使用==和!=進(jìn)行比較了.
if a == a {}
if a != a {}
這里我們?cè)趕wich語(yǔ)句中使用簡(jiǎn)單的匹配模式來(lái)處理。由于MyBool
現(xiàn)在遵循了Equatable
協(xié)議,所以他已經(jīng)自動(dòng)實(shí)現(xiàn)了!=
操作符。再讓我們加一些二進(jìn)制運(yùn)算符:
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)
}
有了基本的運(yùn)算符后,我們就可以實(shí)現(xiàn)各種有用的一元和復(fù)合賦值運(yùn)算符,比如:
prefix func !(a: MyBool) -> MyBool {
return a ^ true
}
// 復(fù)合賦值(按位)
func &=(inout lhs: MyBool, rhs: MyBool) {
lhs = lhs & rhs
}
&=
運(yùn)算符將左邊的運(yùn)算對(duì)象作為inout
對(duì)象,因?yàn)橐獙?duì)它進(jìn)行讀寫(xiě)操作,并且其效果對(duì)于操作者是可見(jiàn)的。Swift提供的值類(lèi)型,使我們可以完全掌控豐富多變的各種操作,比如enum
和struct
。
至此,簡(jiǎn)單的MyBool類(lèi)型已經(jīng)具備了基本的運(yùn)算符操作。希望這篇文章能給你一些思路,使你能夠在自己的代碼中構(gòu)建更高級(jí)更復(fù)雜的類(lèi)型
原文地址:Boolean