Take Dictionary
as an example, suppose I define multiple conditional conformances for it, each having a method with same signature, which one will the compiler choose when I call that method on a dict which has all conformances?
I have run into this scenario a few times. At first I just changed func name to avoid it. But I also did experiments and found compiler behaved as same as my intuition. It looks for the most specific condition. If found, it uses that method; otherwise, it throws ambiguity error.
Setup
struct Foo: Identifiable, Comparable, Hashable {
var id: UUID = UUID()
var value: Int = 0
static func < (lhs: Foo, rhs: Foo) -> Bool {
lhs.value < rhs.value
}
}
Example 1: there is a most specific condition
extension Dictionary where Value: Identifiable {
func get(id: Key) -> Element? {
print("Identifiable version is called")
return nil
}
}
extension Dictionary where Value: Identifiable, Value: Comparable {
func get(id: Key) -> Element? {
print("Identifiable&Comparable version is called")
return nil
}
}
func test1() {
let foo1 = Foo()
let foo2 = Foo()
let foos = [foo1.id: foo1, foo2.id: foo2]
foos.get(id: UUID())
}
Example 2: there isn't one
extension Dictionary where Value: Identifiable, Value: Hashable {
func get(id: Key) -> Element? {
print("Identifiable&Hashable version is called")
return nil
}
}
extension Dictionary where Value: Identifiable, Value: Comparable {
func get(id: Key) -> Element? {
print("Identifiable&Comparable version is called")
return nil
}
}
func test2() {
let foo1 = Foo()
let foo2 = Foo()
let foos = [foo1.id: foo1, foo2.id: foo2]
foos.get(id: UUID())
}
Does anyone know if this is an officially supported feature? I ask because I can't find any mention of this behavior on the net.
EDIT: Another question. What's the recommended solution in example 2 above? Is it possible to give hints to compiler somehow other than changing func name?