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

mrfwxfqh  于 2022-11-06  发布在  Swift
关注(0)|答案(1)|浏览(186)

有人能给予我一个很好的理由,为什么这不工作:

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

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

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
}
hc8w905p

hc8w905p1#

更新:Swift 4.1中已经实现了条件一致性Equatable元素的数组和可选项现在本身是Equatable,您的代码

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

在Xcode 9.3中按预期编译和工作。不再需要这些变通方法。

  • (旧答案:)* 只有当基础 Package 类型可等价时,才能比较可选类型:
public func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool

现在,如果元素类型是equatable,则可以 * 比较 * 数组:

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

但是即使对于可等同的类型x1M2 N1 X,x1M3 N1 X * 也不符合 * x1M4 N1 X协议。
目前,这在Swift中是不可能实现的,例如,参见苹果开发者论坛中的Why can't I make Array conform to Equatable?讨论。这随着Swift 4中SE-0143 Conditional conformances的实现而改变。
您的实现看起来是正确的,下面是一个使用switch/case和模式匹配的可能不同的实现:

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
    }
}

相关问题