为什么Equatable没有为可选数组定义

Sco*_*t H 11 swift swift2

有人能给我一个很好的理由说明为什么这不起作用:

let a: [Int]? = [1]
let b: [Int]? = nil
a == b
Run Code Online (Sandbox Code Playgroud)

这将是我提出的(如果不优雅)解决方案.但这是微不足道的,所以我觉得我错过了一个很好的理由,为什么没有实现.

func ==<T: Equatable>(lhs: [T]?, rhs: [T]?) -> Bool {

    if let lhs = lhs, let rhs = rhs {
        return lhs == rhs
    }
    else if let _ = lhs {
        return false
    }
    else if let _ = rhs {
        return false
    }

    return true
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*n R 18

更新:Swift 4.1中已实现条件一致性.Equatable元素的数组和选项本身就是它们 Equatable和你的代码

let a: [Int]? = [1]
let b: [Int]? = nil
a == b
Run Code Online (Sandbox Code Playgroud)

在Xcode 9.3中编译并按预期工作.不再需要解决方法.


(旧答案:) 只有当底层包装类型相等时,才能比较Optionals:

public func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool
Run Code Online (Sandbox Code Playgroud)

现在可以比较元素类型是否相等的数组:

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

但即使equatable类型T, Array<T> 不符合Equatable协议.

目前,这在Swift中是不可能的,例如, 为什么我不能使Array符合Equatable?在Apple开发者论坛中进行讨论.这一变化与 Swift 4 中SE-0143条件一致性的实现有关.

您的实现看起来是正确的,这里有一个可能不同的使用带模式匹配的开关/案例:

func ==<T: Equatable>(lhs: [T]?, rhs: [T]?) -> Bool {

    switch (lhs, rhs) {
    case let (l?, r?) : // shortcut for (.Some(l), .Some(r))
        return l == r
    case (.None, .None):
        return true
    default:
        return false
    }
}
Run Code Online (Sandbox Code Playgroud)