gpt4 book ai didi

swift - 编译器实现通用协议(protocol)错误

转载 作者:可可西里 更新时间:2023-11-01 00:55:34 24 4
gpt4 key购买 nike

我正在尝试在我的应用程序中使用通用协议(protocol)。我尝试使用的代码是这样的。

protocol BaseProtocol {
associatedtype PresenterType
var presenter: PresenterType? { get set }
}

protocol PresenterProtocol {
associatedtype View
var view: View? { get set }
}

protocol ChildPresenter: PresenterProtocol where View == ChildProtocol {

}

protocol ChildProtocol: BaseProtocol where PresenterType == ChildPresenter {

}


class A: ChildProtocol {
var presenter: ChildPresenter?
}

编译器在遵守 ChildProtocol 时抛出错误

error: protocol 'ChildPresenter' can only be used as a generic constraint because it has Self or associated type requirements var presenter: ChildPresenter?

当我已经清除了我的 associateType 时,我不明白为什么编译器会抛出这个错误。

最佳答案

如错误所述,ChildPresenter olny 可以用作泛型吗,所以你必须把它放在类的声明中,例如。 class A<T: ChildPresenter> : ChildProtocol

protocol BaseProtocol {
associatedtype PresenterType
var presenter: PresenterType? { get set }
}

protocol PresenterProtocol {
associatedtype View
var view: View? { get set }
}

protocol ChildPresenter: PresenterProtocol where View == ChildProtocol {

}

protocol ChildProtocol: BaseProtocol {

}


class A<T: ChildPresenter> : ChildProtocol {
var presenter: T?
func foo(bar: T) {

}
}

您也可以使用 ChildPresenter而不是 T , 像这样

class A<ChildPresenter> : ChildProtocol {
var presenter: ChildPresenter?
}

起初这似乎限制了你的类(class) A ,因为初始化前必须指定ChilPresenter的类型,后面不能修改,但这是必须的,因为ChildPresenter有关联类型。

您可以看到,如果没有泛型,您可能会遇到麻烦,想象一下 BaseProtocol多了一份属性(property)

protocol BaseProtocol {
associatedtype PresenterType
var presenter: PresenterType? { get set }
var presented: PresenterType? { get set }
}

两者都是 presenterpresented必须是同一类型,因为你在这里说了

BaseProtocol declaration with Types highlighted

class A也会有一个属性:

class A<ChildPresenter> : ChildProtocol {
var presenter: ChildPresenter?
var presented: ChildPresenter?
}

这样,您可以保证presenterpresented将始终具有相同的类型,因为您在创建 A 的对象时选择了该类型,例如。 let a = A<Foo>()

A declaration with types hightlighted

如果没有泛型,它看起来像这样

class A: ChildProtocol {
var presenter: ChildPresenter?
var presented: ChildPresenter?
}

这样,presenter可以是 Foo 类型和 presented可以是 Bar 类型.所以你最终会遇到一个悖论。这就是为什么您需要在 A 中设置泛型类型的原因的声明。

关于swift - 编译器实现通用协议(protocol)错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49513649/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com