I can't wrap my head around this. I have the code below. My question is. Why I can not access id in the function compareId (the error, that I am getting is "Value of type 'T.ItemType' has no member 'id'"), but in the function compareIdW I can access the id? Can anyone explain this to me? I will appreciate every help. Thanks
import Foundation
protocol ProtoA: Identifiable{
var id: UUID { get }
}
protocol ProtoB: Identifiable{
associatedtype ItemType = ProtoA
var id: UUID { get }
var arrayOfItems: [ItemType] { get }
}
class M<T:ProtoB>{
var itemA: T.ItemType?
init(itemA: T.ItemType?) {
self.itemA = itemA
}
// This does not work
func compareId(of item: T.ItemType) -> Bool {
return item.id == self.itemA?.id // when
}
// But this does
func compareIdW<U: ProtoA>(of item: U) -> Bool where U == T.ItemType {
return item.id == self.itemA?.id
}
}
CodePudding user response:
It's because T.ItemType
is ambiguous.
At the point that the compiler is looking at your expression all it really knows is that T.ItemType
is an associatedType
. It doesn't really know what properties a particular instance assigned to ItemType
might have.
Consider this code:
struct Marshmallow {
}
struct SmoresStruct : ProtoB {
typealias ItemType = Marshmallow
var id: UUID = UUID()
var arrayOfItems: [Self.ItemType] = Array<Marshmallow>()
}
class SmoresClass : M<SmoresStruct> {
}
SmoresStruct
is a struct
that satisfies the constraint that it implements ProtoB
, and it can be used to create SmoresClass
(a subclass of class M
) because it satisfies all the constraints you've placed on the generic parameter of class M
. But the ItemType
, Marshmallow
, is not Identifiable
so at the point in the implementation of class M
where you try to imply that T.ItemType
should have an id
property, this is one instance where it does not.
You need an additional constraint on your declaration of the M
Class:
class M<T : ProtoB> where T.ItemType : Identifiable {
...
}
Now if you try to use Marshmallow
as an ItemType
you will get:
Type 'SmoresStruct.ItemType' (aka 'Marshmallow') does not conform to protocol 'Identifiable'