教一个(专门的)Swift数组是等于

时间:2016-04-07 02:58:47

标签: arrays swift generics equality swift-protocols

[请投票结束;我同意OP这应该引用Is it possible to add type constraints to a Swift protocol conformance extension?]

我已经玩了一段时间了,显然我并不像我想的那样理解通用协议扩展。我想教一个数组:[NSUUID]Equatable所以我可以使用依赖于Equatable的包装来哈希

这是失败的尝试:

extension Array /* I cannot say ': Equatable' here */ where Element: Equatable {
}


public func ==<T: Equatable> (lhs: [T], rhs: [T]) -> Bool {
    if lhs.count != rhs.count {
        return false
    }
    for (i, v) in lhs.enumerate() {
        if v != rhs[i] {
            return false
        }
    }
    return true
}

我误以为这可能吗?难道我只是桥接到(不幸的是更少类型检查)的NSArray?

澄清

我实际上有一个关于字典的通用包装器,因此它接受两个类型参数:<K: Hashable, V: Equatable>并创建&amp;使用这些维护内部词典。这个包装器的实例化失败了:

class HashWrapper<K, V where K: Hashable, V: Equatable> {
    private var _internalHash: Dictionary<K, V>
    // overload [], do stuff before forwarding it to _internalHash, etc.

    subscript(key: K) -> V? {
        get {
            return _internalHash[key]
        }
        set {
            // *This* is the real reason I wanted Equatable
            if _internalHash[key] == newValue {
                Util.log("Warning: called set with same value as before at key \(key)")
            }
        }
    }
}

修改

这是我目前的解决方案&#34;虽然我不敢比较其他类型的数组,但这种功能在类型上很糟糕但功能很强:

extension Array: Equatable {} // Yes we'll blatantly lie, cannot have both type constraints and protocol conformance

public func ==<T> (lhs: [T], rhs: [T]) -> Bool {
    if lhs.count != rhs.count {
        return false
    }
    for (i, v) in lhs.enumerate() {
        if let nslv = v as? NSObject, nsrv = rhs[i] as? NSObject {
            if nslv != nsrv {
                return false
            }
        }
        else {
            return false // Oh *my*. So very wrong.
        } 
    }
    return true
}

0 个答案:

没有答案