首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过编译器实现泛型协议错误

通过编译器实现泛型协议错误
EN

Stack Overflow用户
提问于 2018-03-27 13:03:48
回答 1查看 62关注 0票数 2

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

代码语言:javascript
复制
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时抛出错误

错误:协议'ChildPresenter‘只能用作泛型约束,因为它具有自或关联类型需求var presenter: ChildPresenter?

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

EN

回答 1

Stack Overflow用户

发布于 2018-03-27 13:26:38

正如错误说的那样,ChildPresenter可以作为泛型使用,所以您必须将它放在类的声明中,例如。class A<T: ChildPresenter> : ChildProtocol

代码语言:javascript
复制
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,如下所示

代码语言:javascript
复制
class A<ChildPresenter> : ChildProtocol {
    var presenter: ChildPresenter?
}

起初,这似乎限制了类A,因为在初始化之前必须指定ChilPresenter的类型,以后不能修改它,但这是必要的,因为ChildPresenter有关联的类型。

您可以看到,如果没有泛型,您可能会遇到麻烦,想象一下BaseProtocol还有一个属性

代码语言:javascript
复制
protocol BaseProtocol {
    associatedtype PresenterType
    var presenter: PresenterType? { get set }
    var presented: PresenterType? { get set }
}

presenterpresented都必须是相同的类型,因为您在这里说过

class A也将拥有更多的财产:

代码语言:javascript
复制
class A<ChildPresenter> : ChildProtocol {
    var presenter: ChildPresenter?
    var presented: ChildPresenter?
}

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

如果没有泛型,它就会像这样

代码语言:javascript
复制
class A: ChildProtocol {
    var presenter: ChildPresenter?
    var presented: ChildPresenter?
}

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

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49513649

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档