Referencing operator function '==' on 'Equatable' requires that 'Dictionary<U, V?>.Values' conform to 'Equatable'

Advertisements

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:

Referencing operator function ‘==’ on ‘Equatable’ requires that ‘Dictionary.Values’ conform to ‘Equatable’

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?

>Solution :

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.

Leave a ReplyCancel reply