Swift error comparing two arrays of optionals

前端 未结 1 1934
小鲜肉
小鲜肉 2021-01-19 17:12

I get a compilation error in the next Swift code

var x:Array = [1,2]
var y:Array = [1,2]
if x == y {  // Error
}
         


        
1条回答
  •  一整个雨季
    2021-01-19 17:49

    The issue here is the distinction between something having an == operator, versus something being “equatable”.

    Both Optional and Array have an == operator, that works when what they contain is equatable:

    // if T is equatable, you can compare each entry for equality
    func ==(lhs: [T], rhs: [T]) -> Bool
    // if T is equatable, you can compare the contents, if any, for equality
    func ==(lhs: T?, rhs: T?) -> Bool
    
    let i: Int? = 1
    let j: Int = 1
    i == j          // fine, Int is Equatable
    ["a","b"] == ["a","b"]  // and so is String
    

    But they themselves do not conform to Equatable. This makes sense given you can put a non-equatable type inside them. But the upshot of this is, if an array contains a non-equatable type, then == won’t work. And since optionals aren’t Equatable, this is the case when you put an optional in an array.

    You'd get the same thing if you tried to compare an array of arrays:

    let a = [[1,2]]
    let b = [[1,2]]
    a == b  // error: `==` can’t be applied to `[Array]`
    

    If you wanted to special case it, you could write == for arrays of optionals as:

    func ==(lhs: [T?], rhs: [T?]) -> Bool {
        if lhs.count != rhs.count { return false }
        for (l,r) in zip(lhs,rhs) {
            if l != r { return false }
        }
        return true
    }
    

    For a counter-example, since Set requires its contents to be hashable (and thus equatable), it can be equatable:

    let setarray: [Set] = [[1,2,3],[4,5,6]]
    setarray == [[1,2,3],[4,5,6]]  // true
    

    0 讨论(0)
提交回复
热议问题