首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Swift:在协议扩展的静态变量中存储协议实现类型

Swift:在协议扩展的静态变量中存储协议实现类型
EN

Stack Overflow用户
提问于 2017-05-20 01:16:17
回答 1查看 834关注 0票数 1

好的,我有一个协议MenuEntry,我想用它填充一个TableView:

代码语言:javascript
复制
protocol MenuEntry {
    static var title: String { get }
    static func entrySelected(_ menuController: MenuController)
}

我想在不同的地方实现这个协议,让项目本身来决定该做什么。它可能是实现协议的UIViewController,也可能是简单的结构,然后调用菜单本身上的函数:

代码语言:javascript
复制
struct SomeEntry: MenuEntry {
    static var title: String { return "Some Entry" }
    static func entrySelected(_ menuController: MenuController) {
        menuController.doSomething()
    }
}

现在,我希望构建MenuControllers数据源,但不实际实例化条目,因为尤其是在填充MenuControllers数据源时,视图控制器不一定可用。这就是为什么我在MenuEntry中使用静态var/func。目前,我只需这样做就可以填充数据源:

代码语言:javascript
复制
let dataSource: [MenuEntry.Type] = [SomeEntry.self]

而且看起来效果很好。我可以获取条目并调用相应的函数:

代码语言:javascript
复制
dataSource.first?.title   //Gives me "Some Entry"

现在出现了棘手的部分。我认为我可以非常聪明地创建一个协议扩展,其中我引用了实现该协议的所有类型,如下所示:

代码语言:javascript
复制
extension MenuEntry {
    static var someEntry: MenuEntry.Type { return SomeEntry.self }
    //...
}

然后再通过MenuEntry.someEntry使用它们。但是,在someEntry上访问MenuEntry会给我一个错误:

代码语言:javascript
复制
error: static member 'someEntry' cannot be used on protocol metatype 'MenuEntry.Protocol'

,所以我的问题是:我错过了什么?我只是试图以一种非故意的方式滥用语言,还是我只是做错了什么?

溶液

从下面被接受的答案来看,我现在是如何做事的。首先,我们需要前面提到的结构(我想不需要一个类):

代码语言:javascript
复制
struct MenuEntries {}

然后,在实现MenuEntry协议的地方,我还扩展了这个结构,并添加了如下条目:

代码语言:javascript
复制
struct SomeEntry: MenuEntry {
    static var title: String { return "Some Entry" }
    static func entrySelected(_ menuController: MenuController) {
        menuController.doSomething()
    }
}

extension MenuEntries {
    static var someEntry: MenuEntry.Type { return SomeEntry.self }
}

最后一件事是像这样创建我的数据源:

代码语言:javascript
复制
let dataSource: [MenuEntry.Type] = [MenuEntries.someEntry, ...]

好的,现在我在一个地方有一张所有菜单条目的列表。缺点是我必须记住每次都要扩展MenuEntries。除了有一些神奇的方法来扩展一个结构的条件基,我不知道。但我想这只是太过了,根本不可能。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-05-20 04:27:01

来自https://itun.es/au/jEUH0.l

协议定义了适合特定任务或功能的方法、属性和其他需求的蓝图。然后,类、结构或枚举可以采用该协议来提供这些需求的实际实现。“

您的扩展试图在协议中直接实现功能,但这是不允许的;只有采用该协议的类、结构或枚举才能提供功能。

您可以定义一个返回菜单类的类:

代码语言:javascript
复制
class MenuFactory {
    static var someEntry: MenuEntry.type { return SomeEntry.self }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44080955

复制
相关文章

相似问题

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