Not sure if this is a bug of some sort, but object
is Equatable
, but still looks like XCode sees it only as Hashable & Identifiable
struct NavigationDestination: Hashable, Equatable, Identifiable {
let object: any Equatable & Hashable & Identifiable
let context: [String:Any]
var id: String {
return self.object.id as! String
}
static func == (lhs: NavigationDestination, rhs: NavigationDestination) -> Bool {
return lhs.object == rhs.object
}
public func hash(into hasher: inout Hasher) {
return hasher.combine(id)
}
}
CodePudding user response:
The ==
operator defined in Equatable
can only compare things of the same type. It seems like you want object
to be able to store anything that is Equatable
, Hashable
and Identifiable
. This means that lhs.object
could be a different type from rhs.object
, and therefore cannot be compared with ==
.
Also note that Hashable
implies Equatable
anyway, so saying Equatable
is redundant. And your id
implementation seems to require that Identifiable.ID
to be String
.
I suggest that you wrap the object
into an AnyHashable
, so that different types of things can be compared for equality. You don't actually need object
to be Identifiable
- you can just assign to id
in the initialiser:
let object: AnyHashable
let id: String
let context: [String:Any]
init<T>(object: T, context: [String: Any]) where T: Hashable, T: Identifiable<String> {
self.context = context
self.object = AnyHashable(object)
self.id = object.id
}
Notice that the complicated type constraints are all moved to the initialiser signature, where you have much more freedom to write type constraints.