Swift中InventoryDictionary遵循Equatable协议的报错解决问询
解决方案
核心问题原因
你遇到的报错是因为Dictionary.Values集合类型的Equatable一致性依赖于其元素(即V?)遵循Equatable协议,而V?要遵循Equatable,必须先让泛型参数V满足Equatable约束。
方案一:给泛型V添加Equatable约束(推荐)
这是最简洁且符合值相等逻辑的解决方案,直接让V遵循Equatable,此时整个字典可以直接用==比较,无需单独拆分keys和values。
代码示例:
class InventoryDictionary<U: Hashable, V: Equatable>: Equatable { var dictionary: [U: V?] = [:] static func == (lhs: InventoryDictionary<U, V>, rhs: InventoryDictionary<U, V>) -> Bool { // 字典本身会自动比较所有键是否匹配,且对应值相等(包括可选值的nil判断) return lhs.dictionary == rhs.dictionary } }
说明:当V遵循Equatable后,V?会自动合成Equatable实现,Dictionary也会自动支持==运算符,其内部会逐一校验键集合的一致性,以及每个键对应值的相等性。
方案二:无Equatable约束下的实例同一性比较(仅适用于引用类型)
如果无法给V添加Equatable约束,且V是引用类型,可通过实例恒等运算符===比较对象是否为同一实例,但这不是值层面的相等判断,局限性较大。
代码示例:
class InventoryDictionary<U: Hashable, V>: Equatable { var dictionary: [U: V?] = [:] static func == (lhs: InventoryDictionary<U, V>, rhs: InventoryDictionary<U, V>) -> Bool { // 先校验键集合是否一致 guard lhs.dictionary.keys == rhs.dictionary.keys else { return false } // 逐个键校验值的实例同一性 for key in lhs.dictionary.keys { switch (lhs.dictionary[key], rhs.dictionary[key]) { case (nil, nil): continue case let (lhsVal?, rhsVal?): guard lhsVal as AnyObject === rhsVal as AnyObject else { return false } default: return false } } return true } }
说明:这个方案仅适用于V是类类型的场景,无法处理值类型的相等判断,因为值类型不能用===比较。
内容的提问来源于stack exchange,提问作者clearlight
相关产品推荐
相关产品推荐

