2016-03-16 88 views
1

我正在试验协议以及如何使用它们来解耦代码,同时利用协议的其他副作用。基本上,我想要做的是以下几点:符合协议的变量子集的Swift通用类型

一个例子可能是API调用的超集,它按范围分组成协议(例如“用户API调用”和“设置API调用”,或“突变API调用“和”突变API调用“)。在这种情况下,有兴趣使用由A公开的API的消费者不一定知道BC的API。

考虑模仿上面的场景以下协议:

protocol A {} 
protocol B {} 
protocol C {} 

然后,给定一组协议[A, B, C],采用了厂级,我想符合的一个子集的API对象的实例这些:

let a = Factory<A>.create() 
let ab = Factory<A, B>.create() 
let bc = Factory<B, C>.create() 

我试图实现,如一个handfuld:

class Factory<T: protocol<A, B, C>> { 
    class func create() -> T { 
     return ... 
    } 
} 

然而,随着let a = Factory<A>.create()初始化产生以下错误:发生

Using 'A' as a concrete type conforming to protocol 'A' is not supported

同样的错误,如果工厂被定义为:

class Factory<T where T: A, T: B> 

有一些明显失败的几件事情:

  • <T: protocol<A, B, C>><T where T: A, T: B>要求返回的对象符合ABC,而不仅仅是它们的一个子集。
  • 鉴于此错误,似乎甚至不可能“将协议用作符合协议的具体类型”。

总之,它甚至有可能实现什么,我想?

回答

0

我就把你使用泛型在你的情况,我很可能也看协议继承。

因此,例如,一个可变协议将从不变协议继承,因为你要能够访问作为替代的情况下,最小和接入和变化。

协议的目的是将您从底层的实现类中抽象出来。在你的例子中,泛型并没有真正增加这种能力。您的工厂(或工厂)可以简单地提供许多创建方法,以返回符合各种协议的对象。

要继续使用泛型意味着暴露下面的实现类,这是您的错误的原因。你不能使用协议,因为它不具体,它只是一些具体对象将提供的定义。

+0

我同意与可变/不可变的例子,协议继承是优选的,但与其他实施例,不认为它是。根据我的经验,将相关行为按照描述分组为协议是一种常见的方法。但是,对于协议(a,b,c,ab,ac,bc,abc)的每个单一组合都具有创建功能可能不是所期望的。无论如何,它是否正确地被理解为我不能只使用泛型协议(''),但是我需要一个类型,然后我可以要求它符合给定的协议(' )? –

+0

我明白了,谢谢澄清。你认为这是Swift的限制吗?如果是这样,这个限制的原因是什么? “我能否拥有符合本协议的某个对象”这个问题在我看来是不无道理的。 –

相关问题