为什么我无法访问 swift 中的通用成员

Why I can not access member of generic in swift

我无法解决这个问题。我有下面的代码。我的问题是。为什么我无法在函数 compareId 中访问 id(我得到的错误是“类型 'T.ItemType' 的值没有成员 'id'”),但在函数 compareIdW 中我可以访问 id?谁能给我解释一下?我会感激每一个帮助。谢谢

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
    }

}

因为T.ItemType有歧义

在编译器查看您的表达式时,它真正知道的是 T.ItemType 是一个 associatedType。它真的不知道分配给 ItemType 的特定实例可能具有哪些属性。

考虑这段代码:

struct Marshmallow {
}

struct SmoresStruct : ProtoB {
    typealias ItemType = Marshmallow

    var id: UUID = UUID()
    var arrayOfItems: [Self.ItemType] = Array<Marshmallow>()
}

class SmoresClass : M<SmoresStruct> {
} 

SmoresStruct 是一个 struct 满足它实现 ProtoB 的约束,它可以用来创建 SmoresClass([=20= 的子类) ]) 因为它满足您对 class M 的通用参数设置的所有约束。但是 ItemTypeMarshmallow 不是 Identifiable 所以在 class M 的实现中你试图暗示 T.ItemType 应该有一个 id 属性,这是一个没有的例子。

您需要对 M Class:

的声明进行额外约束
class M<T : ProtoB> where T.ItemType : Identifiable {
   ...
}

现在,如果您尝试将 Marshmallow 用作 ItemType,您将得到:

Type 'SmoresStruct.ItemType' (aka 'Marshmallow') does not conform to protocol 'Identifiable'