Swift, Equatable protocol bug?

2019-07-06 01:30发布

问题:

I am building a very simple structure in Swift that contains an array of optional values. This struct must conform to the Equatable protocol. This is the code:

struct MyTable: Equatable {
    var values: [Int?] = Array(count: 64, repeatedValue: nil)
}

func == (lhs: MyTable, rhs: MyTable) -> Bool {
    return lhs.values == rhs.values
}

Quite simple. I see no mistakes, but the compiler gives error: "'[Int?]' is not convertible to 'MyTable'". Am I doing something stupid? or is this a compiler's bug? Thanks!

(Using Xcode6-Beta5)

回答1:

The reason why it does not work is there is no == operator defined for arrays with optional elements, only for non-optional elements:

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

You can provide your own:

func ==<T : Equatable>(lhs: [T?], rhs: [T?]) -> Bool {
    if lhs.count != rhs.count {
        return false
    }

    for index in 0..<lhs.count {
        if lhs[index] != rhs[index] {
            return false
        }
    }

    return true
}


回答2:

Another useful option is to use the elementsEqual:isEquivalent: method available on SequenceType. This could allow you to avoid implementing Equatable, but is best used rarely as it is more verbose.

Usage:

let a: [Int?] = []
let b: [Int?] = []

if a.elementsEqual(b, isEquivalent: { $0 == $1 }) {
    print("foo") // Works
}