【问题标题】:Why I can not access member of generic in swift为什么我无法快速访问泛型成员
【发布时间】:2021-10-20 20:59:46
【问题描述】:

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

}

【问题讨论】:

    标签: swift generics swift-protocols


    【解决方案1】:

    这是因为T.ItemType 不明确。

    当编译器正在查看您的表达式时,它真正知道的是T.ItemTypeassociatedType。它并不真正知道分配给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 的约束,并且它可以用于创建SmoresClassclass M 的子类),因为它满足您放置的所有约束在class M 的泛型参数上。但是ItemTypeMarshmallow 不是Identifiable,所以在class M 的实现中,你试图暗示T.ItemType 应该有一个id 属性,这是它的一个实例不是。

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

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

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

    类型“SmoresStruct.ItemType”(又名“Marshmallow”)不符合协议“Identifiable”

    【讨论】:

    • 感谢您的回答,清晰简单的解释。
    猜你喜欢
    • 2019-10-20
    • 2020-08-02
    • 1970-01-01
    • 1970-01-01
    • 2013-10-14
    • 2010-12-20
    • 2020-09-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多