我在下面的代码片段中发现错误“StreamingModel”不能转换为“T.EAModel”。有人能帮我理解这个错误吗。

public struct GraphViewsMainSUI<T> : View where T: GraphViewRepresentableProtocol {

    @ObservedObject public var graphToggle: GraphToggle
    @ObservedObject public var model: StreamingModel

    public var body: some View {
        HStack {
            VStack {
                Text("Select Graphs").font(.headline)
                GroupBox{
                    GraphChecksSUI(toggleSets: $graphToggle.toggleSets)
                }
            }.padding(.trailing, 35)
            T(model: model, toggleSets: $graphToggle.toggleSets)   <<<< COMPILE ERROR HERE
        }.frame(minWidth: 860, idealWidth: 860, maxWidth: .infinity, minHeight: 450, idealHeight: 450, maxHeight: .infinity).padding()
    }
}

public protocol GraphViewRepresentableProtocol: NSViewRepresentable  {

    associatedtype EAModel

    init(model: EAModel, toggleSets: Binding<[GraphToggleSet]>)

}

我正在为符合GraphViewRepresentable的类型T使用的结构如下。
public struct GraphViewRepresentable: NSViewRepresentable, GraphViewRepresentableProtocol {

    public var model: StreamingModel
    @Binding public var toggleSets: [GraphToggleSet]

    public init(model: StreamingModel, toggleSets: Binding<[GraphToggleSet]>) {
        self.model = model
        self._toggleSets = toggleSets
    }
    ...
}

在协议中,associatedtype没有限制,所以我不明白为什么编译器没有将EAModel类型设置为StreamingModel。

最佳答案

在这里:

T(model: model, toggleSets: $graphToggle.toggleSets)

您假设无论T是什么,都有一个关联的类型EAModel == StreamingModel,这不一定是真的。我可以输入这样的类型:
struct Foo : GraphViewRepresentableProtocol {
    typealias EAType = Int
    init(model: EAModel, toggleSets: Binding<[GraphToggleSet]>) { }
}

你的密码就会被破解。
您可能需要将T进一步约束到具有EAModel == StreamingModel的类型集:
public struct GraphViewsMainSUI<T> : View where T: GraphViewRepresentableProtocol, T.EAModel == StreamingModel {

关于swift - 为什么我 swift 得到“X不可转换为T.Y”?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58281366/

10-12 14:43