Swift:不能将协议与泛型混合

Posted

技术标签:

【中文标题】Swift:不能将协议与泛型混合【英文标题】:Swift: cannot mix protocols with generics 【发布时间】:2015-03-14 18:16:33 【问题描述】:

假设我有以下代码:

protocol A 
struct B: A 

func b() -> A 
    return B()


func f<T where T: A>(t: T) -> T 
    return t


f(b())

这会导致以下错误(Xcode 6.3 beta 3):

Playground 执行失败:Test.playground:12:1: 错误:泛型参数“T”不能绑定到非@objc 协议类型“A”

f(b())
^
Test.playground:8:6: note: in call to function 'f'
func f<T where T: A>(t: T) -> T 
     ^

我觉得这是在 Swift 中实现泛型的一个缺点。有没有办法很好地解决这个问题,同时仍然保留泛型?

在我的代码f() 中有额外的类型要求;我可以完全忘记协议和泛型,但我不接受那么容易的失败;-)。

【问题讨论】:

取决于您的用例,但如果可能的话,我会尝试通过将b() 定义为泛型来避免类型擦除B 并返回实际类型... 但是如果我需要b 需要通用呢? 【参考方案1】:

这里可能不允许隐式向下转换,您需要在方法 b() 的实现中强制它:

func b () -> A 
return B() as A

【讨论】:

【参考方案2】:

如果您使用@objc 标记协议并将结构更改为类,它将起作用,因为这样您将处于存在不同规则的Objective C 兼容领域。

原因是在 Swift 中,由于协议和/或关联类型的可能静态要求,协议不被认为是它们自身的具体实现。在我看来,这确实是 Swift 的一个(非常烦人的)缺点。另见问题:

Protocol doesn't conform to itself?

【讨论】:

以上是关于Swift:不能将协议与泛型混合的主要内容,如果未能解决你的问题,请参考以下文章

具有泛型的Swift函数,其中约束是自身符合的协议

Swift 泛型和协议扩展

Xcode/Cocoapods 为啥我不能从 Pod 实现 Swift 协议?

符合 Swift 协议的泛型类型

swift 协议示例在Swift中展示泛型

Swift:检查泛型类型是不是符合协议