I'm having trouble getting Swift to understand that an array of objects that conform to two protocols is the same as an array that conforms to one of them.
Let's say I have two protocols, Identifiable and Namable:
protocol Identifiable {
var identifier: Int { get }
}
protocol Namable {
var name: String { get }
}
And two functions that will print info about arrays of objects conforming to those protocols:
func printIdentifiers(itemsToPrint: [Identifiable]) {
for (itemNumber, item) in itemsToPrint.enumerate() {
print("\(itemNumber): \(item.identifier)")
}
}
func printNames(itemsToPrint: [Namable]) {
for (itemNumber, item) in itemsToPrint.enumerate() {
print("\(itemNumber): \(item.name)")
}
}
And then two structs that conform to those protocols:
struct Friend: Identifiable, Namable {
var identifier: Int
var name: String
}
struct Dog: Identifiable, Namable {
var identifier: Int
var name: String
}
And then say I have an array of items that conform to both those protocols:
let jeff = Friend(identifier: 232314, name: "Jeff")
let fido = Dog(identifier: 45678, name: "Fido")
let identifiableAndNamableItems: [protocol<Identifiable, Namable>] = [jeff, fido]
Swift has no problem when I assign jeff
to a variable that's Namable
:
let namableJeff: Namable = jeff //This is fine!
But it freaks out when I try to do:
printNames(identifiableAndNamableItems)
Cannot convert value of type [protocol<Identifiable, Namable>] to expected argument type [Namable]
Any idea why? Swift knows intuitively that a variable with type protocol<Identifiable, Namable>
can be assigned to a variable with type Namable
, since any object that conforms to two protocols must necessarily conform to just one of the protocols. But it does not understand that an array of items that conform to two protocols can be assigned to an array of items that conform to one of the protocols.