Swift類型建立之自訂一個類型詳解_Swift

來源:互聯網
上載者:User

小夥伴們,Swift中的Bool類型有著非常重要的文法功能,並支撐起了整個Swift體系中的邏輯判斷體系,經過老碼的研究和學習, Bool類型本身其實是對基礎Boolean類型封裝,小夥伴們可能咬著手指頭問老碼,怎麼一會Bool類型,一會Boolean類型,其區別在於,前者是基於枚舉的組合類別型,而後者則是基本類型,只有兩種true和false。

####自訂原型

接下老碼根據Bool的思想來建立一個OCBool類型,來讓小夥伴們瞭解一下Swift中到底是怎麼玩兒的。

來我們先看一下OCBool的定義。

#####程式碼範例如下:

複製代碼 代碼如下:

enum OCBool{
case ocTrue
case ocFalse
}

#####注意:

代碼中第2行和第3行,可以合并到一行寫,如蘋果官方Blog所寫的一樣
代碼中命名需要注意:OCBool是類型名,所以首字母必須大寫,而case中的ocTrue和ocFalse是小類型則需要首字母小寫。

####實現預設值

行,我們給了一個漂亮的定義,不過按照傳統語言的經驗,Bool值預設情況下是假, 所以我們的OCBool也應該如此,我們使用類型擴充技術增加這個預設特性:

複製代碼 代碼如下:

extension OCBool{
     init(){
             self =.ocFalse
     }
}

#####注意:

●代碼中第1行:extension關鍵字,非常強大,小夥伴們可以通過此創造出許多好玩的東西,建議各位去Github上看一個名為“Swiftz”的項目,它將擴充用到了極致。

●代碼中第3行:self = .ocFalse文法,剛入門的小夥伴們很迷糊,為什麼會有奇怪的點文法,因為大牛Chris在Swift中增加了類型智能推斷功能,在蘋果Blog中,提到了“Context”概念,就是這個意思,因為這行語句是在枚舉OCBool中的,其上下文就是OCBool的定義體,編譯器當然知道.ocFalse就是OCBool.ocFalse了,所以這裡直接點文法,非常整齊。

現在我們可以使用如下方法使用這個Bool類型。

#####程式碼範例如下:

複製代碼 代碼如下:

var result:OCBool = OCBool()
var result1:OCBool = .ocTrue

####支援基本布爾型初始化

正如上述代碼所述,我們只能通過類型或者枚舉項目賦值,這是組合類別型的用法,但是編碼的日子裡,我們總是希望和true,false直接打交道,也就是說,我們希望這麼做,

程式碼範例如下:

複製代碼 代碼如下:

var isSuccess:OCBool = true

如果小夥伴們直接這麼用,則會出現如下錯誤:
複製代碼 代碼如下:

/Users/tyrion-OldCoder/Documents/Learning/BoolType/BoolType/main.swift:30:24: Type 'OCBool' does not conform to protocol 'BooleanLiteralConvertible'

編譯器咆哮的原因是,我們的類型沒有遵從“布爾字面量轉換協議”,接下來修正這個問題,

#####程式碼範例如下:

複製代碼 代碼如下:

import Foundation

println("Hello, World!")

enum OCBool{
    case ocTrue
    case ocFalse
}


extension OCBool: BooleanLiteralConvertible{
static func convertFromBooleanLiteral( value: Bool) ->OCBool{
    return value ? ocTrue : ocFalse
    }
}

var isSuccess:OCBool = true

#####注意:

代碼中的第11行是重點,我的類型OCBool支援了BooleanLiteralConvertible協議,這個協到底是幹什麼的呢,小夥伴們在Xcode代碼編輯器,按住Command鍵,然後點擊第11行中的BooleanLiteralConvertible協議名,則會進入它的定義,

#####其定義如下:

複製代碼 代碼如下:

protocol BooleanLiteralConvertible {
    typealias BooleanLiteralType
    class func convertFromBooleanLiteral(value: BooleanLiteralType) -> Self
}

這個定義中有個類方法convertFromBooleanLiteral,它的參數為BooleanLiteralType類型,也就是我傳入的Bool類型, 且傳回值為實現這個協議的類型本身,在我們的OCBool類型中,其傳回值就是OCBool本身。經過這個定義,我們可以直接對OCBool類型直接進行布爾字面量初始化了。

####支援Bool類型判斷

小夥伴們不安分, 肯定想著我怎麼用它實現邏輯判斷,所以如果你這麼寫,
#####程式碼範例如下:

複製代碼 代碼如下:

var isSuccess:OCBool = true

if isSuccess {
    println( "老碼請你吃火鍋!")
}


你永遠吃不到老碼的火鍋,因為這裡編譯器會咆哮:
複製代碼 代碼如下:

/Users/tyrion-OldCoder/Documents/Learning/BoolType/BoolType/main.swift:27:4: Type 'OCBool' does not conform to protocol 'LogicValue'

OCBool現在只能用bool類型初始化,而不能直接返回bool型,小火把們還記得在《老碼說編程之白話Swift江湖》中,老碼多次提到,媽媽再也不擔心我們 if a = 1{}的寫法了, 因為等號不支援值返回了, 所以在if判斷是後面的條件必須有傳回值,OCBool沒有,所以編譯器哭了。我們解決這個問題。
#####程式碼範例如下:

複製代碼 代碼如下:

import Foundation

println("Hello, World!")

enum OCBool{
    case ocTrue
    case ocFalse
}


extension OCBool: BooleanLiteralConvertible{
static func convertFromBooleanLiteral( value: Bool) ->OCBool{
    return value ? ocTrue : ocFalse
    }
}

extension OCBool: LogicValue{
    func getLogicValue() ->Bool {
        var boolValue: Bool{
        switch self{
        case .ocTrue:
            return true
        case .ocFalse:
            return false
            }
        }
        return boolValue
    }
}


var isSuccess:OCBool = true

if isSuccess {
    println( "老碼請你吃火鍋!")
}

####運行結果如下:

複製代碼 代碼如下:

Hello, World!
老碼請你吃火鍋!
Program ended with exit code: 0

#####注意:

●如果小夥伴們現在用的是Beta版的Xcode,注意蘋果官方Blog中,在代碼第17行如果在Xcode Beta4下是錯誤的,這裡的協議是,LogicValue而不是BooleanVue,所以記得看錯誤提示才是好習慣。

●注意代碼第34行,完美支援if判斷,且輸出結果為“老碼請你吃火鍋”,老碼也是說說而已,請不要當真。

####支援相容各們各派的類型

小夥伴們,江湖風險,門派眾多,老碼有自己的OCBool類型,可能嵩山少林有自己的SSBool類型,甚至連郭美美都可能有自己的MMBool類型,所以OCBool必須能夠識別這些類型,這些各門各派的類型,只要支援LogicValue協議,就應該可以被識別,看老碼怎麼做,

#####程式碼範例如下:

複製代碼 代碼如下:

extension OCBool{
    init( _ v: LogicValue )
    {
        if v.getLogicValue(){
            self = .ocTrue
        }
        else{
            self = .ocFalse
        }
    }

}

var mmResult: Bool = true
var ocResult:OCBool = OCBool(mmResult)


if ocResult {
    println( "老碼沒錢,郭美美請你吃火鍋!")
}

#####代碼運行結果如下:

複製代碼 代碼如下:

Hello, World!
老碼沒錢,郭美美請你吃火鍋!
Program ended with exit code: 0

漂亮!我們的OCBool類型現在支援了所有的邏輯變數初始化。

#####注意:

●代碼中第2行:“_”下橫杠的用法,這是一個功能強大的小強,在此的目的是屏蔽外部參數名,所以小夥伴們可以直接:var ocResult:OCBool = OCBool(mmResult)而不是:var ocResult:OCBool = OCBool(v: mmResult),小夥伴們驚呆了!這個init函數中本來就沒有外部參數名啊,還記得老碼在書裡說過沒,Swift的初始化函數會預設使用內部參數名,作為外部參數名。

####完善OCBool的布爾基因體系:
小夥伴們,bool類型的價值就是在於各種判斷,諸如==,!=, &,|,^,!,以及各種組合邏輯運算,我們OCBool也要具備這些功能,否則就會基因缺陷,且看老碼如何?:

複製代碼 代碼如下:

extension OCBool: Equatable{
}

//支援等值判斷運算子
func ==( left: OCBool, right: OCBool )->Bool{
    switch (left, right){
    case (.ocTrue, .ocTrue):
            return true
    default:
        return false
    }
}
//支援位與運算子
func &( left:OCBool, right: OCBool)->OCBool{

    if left{
        return right
    }
    else{
        return false
    }
}
//支援位或運算子
func |( left:OCBool, right: OCBool)->OCBool{

    if left{
        return true
    }
    else{
        return right
    }
}

//支援位異或運算子
func ^( left:OCBool, right: OCBool)->OCBool{
    return OCBool( left != right )
}
//支援求反運算子
@prefix func !( a:OCBool )-> OCBool{
    return a ^ true
}
//支援組合求與運算子
func &= (inout left:OCBool, right:OCBool ){
    left = left & right
}


var isHasMoney:OCBool = true
var isHasWife:OCBool = true
var isHasHealty:OCBool = true
var isHasLover:OCBool = true

isHasMoney != isHasHealty
isHasHealty == isHasMoney
isHasWife ^ isHasLover
isHasWife = !isHasLover

if (isHasMoney | isHasHealty) & isHasHealty{
    println( "人生贏家,就像老碼一樣!")
}else
{
    println("人生最苦的事事,人死了錢沒花了,人生最苦的事是,人活著,錢沒了!")
}


好了,到這裡就到這裡了,窗外的雷聲叫醒了老碼,現在應該去吃飯了,以上老碼給大家展示了如果製造一個自己的類型,記得老碼的樣本是在Xcode6 Beta4下測試的,至於Beta5的改變還沒有涉及,小夥伴們要好生練習,以後各種自定類型都是基於這個思想。還有這個章節不是老碼的原創,老碼認真的閱讀了蘋果的官方部落格,且自己的練習總結,如果小夥伴們費了吃奶的勁還是看不懂,請找度娘Google♂♂♂

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.