swift中文 - swift version



嵌套數組上的Swift相等運算符 (2)

你可以通過為它實現一個 == 函數來完成它,如下所示:

func == (lhs: [[Simple]], rhs: [[Simple]]) -> Bool {
    //your code
}

https://src-bin.com

為什麼最後一個語句無法使用​​錯誤進行編譯: Binary operator '==' cannot be applied to two '[[Simple]]' operands ,並且有一種方法可以修改 Simple 結構或將 == 運算符擴展為能夠對嵌套數組(或字典)執行相等性檢查嗎?

var i1: [Int] = [1]
var i2: [Int] = [1]
i1 == i2 // -> true


var i3: [[Int]] = [[1], [2]]
var i4: [[Int]] = [[1], [2]]
i3 == i4 // -> true


struct Simple: Equatable, Hashable {
    let message: String

    var hashValue: Int {
        return message.hashValue
    }
}
func ==(lhs: Simple, rhs: Simple) -> Bool {
    return lhs.message == rhs.message
}

var a: [Simple] = [Simple(message: "a")]
var b: [Simple] = [Simple(message: "a")]
a == b // -> true

var x: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]]
var y: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]]
x == y // -> ERROR! Binary operator '==' cannot be applied to two '[[Simple]]’ operands

Answer #1

更新: Swift 4.1中 已實現條件一致性 特別是:

標準庫類型Optional,Array和Dictionary現在符合Equatable協議,當它們的元素類型符合Equatable時。 ...

(來自Swift CHANGELOG )。

任意嵌套的 Equatable 元素 Equatable 現在都是 Equatable ,可以與 == 進行比較。 你的代碼

var x: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]]
var y: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]]
x == y

如果 SimpleEquatable 則在Xcode 9.3中編譯。

(舊答案:) 原因類似於 為什麼Equatable沒有為可選數組定義 。 如果元素類型是 Equatable 則可以將數組與 == 進行 比較

/// Returns true if these arrays contain the same elements.
public func ==<Element : Equatable>(lhs: [Element], rhs: [Element]) -> Bool

這就是為什麼

var a: [Simple] = [Simple(message: "a")]
var b: [Simple] = [Simple(message: "a")]
a == b // -> true

編譯。

但即使對於等價類型 TArray<T> 也不符合 Equatable 協議,比較 為什麼我不能使Array符合Equatable? 。 因此,在

var x: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]]
var y: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]]
x == y // -> ERROR! Binary operator '==' cannot be applied to two '[[Simple]]’ operands

xy 是元素類型 [Simple] 數組,它不符合 Equatable 協議,並且沒有匹配的 == 運算符。

您可以為簡單嵌套數組定義泛型 == 運算符

func ==<Element : Equatable> (lhs: [[Element]], rhs: [[Element]]) -> Bool {
    return lhs.count == rhs.count && !zip(lhs, rhs).contains {$0 != $1 }
}

或更簡單(如@kennytm所建議的):

func ==<Element : Equatable> (lhs: [[Element]], rhs: [[Element]]) -> Bool {
    return lhs.elementsEqual(rhs, by: ==)
}

這使 x == y 編譯並按預期工作。 目前,似乎無法在任意嵌套數組上定義 == 運算符。





swift