首页 > 解决方案 > 为什么我无法快速访问泛型成员

问题描述

我无法解决这个问题。我有下面的代码。我的问题是。为什么我无法在函数 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
    }

}

标签: swiftgenericsswift-protocols

解决方案


就是因为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是 astruct满足它实现的约束ProtoB,并且它可以用于创建SmoresClass(的子类class M),因为它满足您对 的泛型参数施加的所有约束class M。但是ItemType, ,在你试图暗示应该有一个属性的实现中Marshmallow并不是这样,这是一个没有属性的实例。Identifiableclass MT.ItemTypeid

您需要对类的声明进行额外的限制M

class M<T : ProtoB> where T.ItemType : Identifiable {
   ...
}

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

类型“SmoresStruct.ItemType”(又名“棉花糖”)不符合协议“可识别”


推荐阅读