Equatable和Comparable

上一篇:一個整數(shù)的誕生

Equatable和Comparable

上次我們談了Swift標(biāo)準(zhǔn)庫是如何通過一系列protocol來定義一個整數(shù)的,今天我們進(jìn)一步深入標(biāo)準(zhǔn)庫源代碼,看看這些protocol的真面目。

1. Equatable

我們從最簡單的Equatable開始,這是Swift標(biāo)準(zhǔn)庫最基本的協(xié)議之一:

// file: Equatable.swift

public protocol Equatable {
    static func == (lhs: Self, rhs: Self) -> Bool
}

extension Equatable {
    @_inlineable
    @_transparent
    public static func != (lhs: Self, rhs: Self) -> Bool {
        return !(lhs == rhs)
    }
}

Equatable表達(dá)的concept簡單明了:如果一個type的實(shí)例可以比較相等性(equality),那這個type就是equatable,用Swift的語言表示就是

func ==(lhs:rhs:)

2. Comparable

Comparable表達(dá)的概念比Equatable更多了一層:除了比較相等性之外,還應(yīng)該可以比較大小。

// file: Comparable.swift

public protocol Comparable : Equatable {
    static func < (lhs: Self, rhs: Self) -> Bool
    static func <= (lhs: Self, rhs: Self) -> Bool
    static func >= (lhs: Self, rhs: Self) -> Bool
    static func > (lhs: Self, rhs: Self) -> Bool
}

Comparable一共定義了六個方法(別忘了還有兩個繼承自Equatable),也就是說一個type要是遵從Comparable協(xié)議,就必須實(shí)現(xiàn)這六個方法。不過不必?fù)?dān)心,標(biāo)準(zhǔn)庫已經(jīng)很貼心地為其中的四個方法提供了默認(rèn)的實(shí)現(xiàn),用戶只需要提供==<就可以了。

// file: Comparable.swift

extension Comparable {
    @_inlineable
    public static func > (lhs: Self, rhs: Self) -> Bool {
        return rhs < lhs
    }

    @_inlineable
    public static func <= (lhs: Self, rhs: Self) -> Bool {
        return !(rhs < lhs)
    }

    @_inlineable
    public static func >= (lhs: Self, rhs: Self) -> Bool {
        return !(lhs < rhs)
    }
}

3. 一個例子

我們通過一個例子來說明Comparable的用法,這個例子取自Swift官方文檔:

// 一個自定義類型
struct Date {
    let year: Int
    let month: Int
    let day: Int
}

// 我們希望Date遵從Comparable協(xié)議
extension Date: Comparable {
    // Equatable
    // 不需要定義 !=,因為已有默認(rèn)實(shí)現(xiàn)
    static func ==(lhs: Date, rhs: Date) -> Bool {
        return lhs.year == rhs.year && lhs.month == rhs.month
            && lhs.day == rhs.day
    }

    // Comparable
    // 不需要定義 <=, >, >=,因為已有默認(rèn)實(shí)現(xiàn)
    static func <(lhs: Date, rhs: Date) -> Bool {
        if lhs.year != hrs.year {
            return lhs.year < rhs.year
        } else if lhs.month != rhs.month {
            return lhs.month < rhs.month
        } else {
            return lhs.day < rhs.day
        }
    }
}

let spaceOddity = Date(year: 1969, month: 7, day: 11)
let moonLanding = Date(year: 1969, month: 7, day: 20)

if moonLanding > spaceOddify {
    print("Major Tom stepped through the door first.")
} else {
    print("David Bowie was following in Neil Armstrong's footsteps.")
}
// Prints "Major Tom stepped through the door first."
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容