英文:
Referencing operator function '==' on 'Equatable' requires that 'Dictionary<U, V?>.Values' conform to 'Equatable'
问题
我有一个定义字典的类:
class InventoryDictionary<U: Hashable, V>: Equatable {
var dictionary: [U: V?] = [:]
static func ==(lhs: InventoryDictionary, rhs: InventoryDictionary) -> Bool {
return lhs.dictionary.keys == rhs.dictionary.keys
&& lhs.dictionary.values == rhs.dictionary.values
}
}
XCode显示错误:
<blockquote>
引用 '==' 操作符函数 'Equatable' 要求 'Dictionary<U, V?>.Values' 符合 'Equatable'
</blockquote>
我试图使 InventoryDictionary 符合 `Equatable` Swift 协议。
在 `==` 重载函数中,`dictionary.keys` 可以进行相等比较,但值(这是可以理解的,有点)不能。
但从消息中我不清楚是否可以在不编写代码来检查每个 `V`(值)的情况下解决这个问题,或者是否有办法使 Swift 的泛型 `V` 可比较。
这方面有什么好的方法吗?
英文:
I have a class that defines a dictionary:
class InventoryDictionary <U : Hashable, V> : Equatable {
var dictionary : [ U : V? ] = [:]
static func ==(lhs: InventoryDictionary, rhs: InventoryDictionary) -> Bool {
return lhs.dictionary.keys == rhs.dictionary.keys
&& lhs.dictionary.values == rhs.dictionary.values
}
}
XCode shows an error:
<blockquote>
Referencing operator function '==' on 'Equatable' requires that 'Dictionary<U, V?>.Values' conform to 'Equatable'
</blockquote>
I'm trying to make InventoryDictionary conform to the Equatable
Swift protocol.
In the ==
overload function, dictionary.keys
can be compared for equality but not the values (which is understandable, kind of).
But it isn't clear to me from the message whether or not that's solvable without me writing code to check each V
(value) or whether there's some way to make Swift-generic V
equatable.
What's a good approach to this?
答案1
得分: 2
Here's the translated code portion:
首先,V
也必须是 Equatable
。也就是说,声明应该是
class InventoryDictionary<U: Hashable, V: Equatable>: Equatable {
但是,你不应该使用 class
。最好你应该使用 struct
,因为这样等式性(equatability)将会自动生成。
struct InventoryDictionary<U: Hashable, V: Equatable>: Equatable {
var dictionary: [U: V] = [:]
}
如果你真的需要这是一个引用类型:
class InventoryDictionary<U: Hashable, V: Equatable>: Equatable {
var dictionary: [U: V] = [:]
static func ==(lhs: InventoryDictionary, rhs: InventoryDictionary) -> Bool {
return lhs.dictionary == rhs.dictionary
}
}
注意,我还从字典值中移除了可选项。除非你真的非常希望存储带有 nil
值的键,否则不应该出现它。
英文:
First of all, V
must be Equatable
, too. That is, the declaration should be
class InventoryDictionary<U: Hashable, V: Equatable> : Equatable {
However, you shouldn't use a class
. Preferably you should use a struct
for this use case because then equability will be generated for you.
struct InventoryDictionary<U: Hashable, V: Equatable> : Equatable {
var dictionary: [U: V] = [:]
}
If you really need this to be a reference type:
class InventoryDictionary<U: Hashable, V: Equatable> : Equatable {
var dictionary: [U: V] = [:]
static func ==(lhs: InventoryDictionary, rhs: InventoryDictionary) -> Bool {
return lhs.dictionary == rhs.dictionary
}
}
Note that I have also removed the optional from the dictionary value. It shouldn't be there unless you really really want to store keys with a nil
value.
答案2
得分: 2
如果V
的可哈希性和可相等性不是InventoryDictionary
的固有特性(即它们仅用于符合Hashable
和Equatable
),那么您可以使用条件符合:
// `U` has to be `Hashable` in any case, because it's used as a key
class InventoryDictionary<U: Hashable, V> {
var dictionary: [U: V?] = [:]
// ...
}
extension InventoryDictionary: Equatable where V: Equatable {}
extension InventoryDictionary: Hashable where V: Hashable {}
英文:
To add to Sulthan's answer:
If the hashability and equability of V
aren't intrinsic to the InventoryDictionary
(i.e. they're only needed for the conformances to Hashable
and Equatable
), then you can use conditional conformances:
// `U` has to be `Hashable` in any case, because it's used as a key
class InventoryDictionary<U: Hashable, V> {
var dictionary: [U: V?] = [:]
// ...
}
extension InventoryDictionary: Equatable where V: Equatable {}
extension InventoryDictionary: Hashable where V: Hashable {}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论