purrrminator purrrminator - 1 year ago 64
Swift Question

Swift: equatable dictionary cannot be passed to a generic function

I really need to pass any equatable structs/types/objects to this

Any idea how can I solve this problem?
enter image description here

Update: I'm not asking "how to compare dictionaries?". My question doesn't duplicate anything. As you can see in the picture, I'm able to compare them, but unable to pass as Equatable generic.

public func ==(l: [String: String], r: [String: String]) -> Bool {
return true // just a stub

func setEquatable<T: Equatable>(v: T) {

let isEqual = ["1": "2"] == ["1": "2"]
setEquatable(v: ["1": "2"])

Answer Source

This is currently a limitation of Swift's type system that is well-known and on the roadmap to fix. The specific feature being discussed to fix this is "conditional conformance" to protocols for generic types. In essence, the Dictionary type can't be universally declared Equatable, because you don't know up front how to compare every possible type of value it may hold (some of which might not themselves be Equatable).

Conditional conformance would allow you to create an extension that says that Dictionary sometimes conforms to Equatable, specifically under the condition when its Value type is Equatable. And in that case, Dictionary equality can be defined as a function that compares the equality of all keys and all values in both Dictionary instances being checked.

Here is a summary of this feature and others under consideration:


Until this type system upgrade is implemented though, there is unfortunately no way to treat any Dictionary as Equatable directly. You can however create Equatable-conforming wrapper types around Dictionaries, or overload your setEquatable function to also accept Dictionaries with Equatable values and handle accordingly.