为实现多个协议的任何对象定义一个 Swift 类型别名

Posted

技术标签:

【中文标题】为实现多个协议的任何对象定义一个 Swift 类型别名【英文标题】:Define a Swift typealias for any object that implements multiple protocols 【发布时间】:2015-04-18 08:22:22 【问题描述】:

我正在尝试为符合多种协议的 UITableViewCell 的委托属性定义 typealias。这就是我正在尝试做的事情,Swift 抱怨我的语法错误:

// The typealias definition
typealias CellDelegate = AnyObject<UIPickerViewDataSource, UIPickerViewDelegate>

// In my UITableViewCell subclass:
weak var delegate: CellDelegate?

“不能专门化非泛型类型 AnyObject”是我得到的错误。我该如何正确地做到这一点?

【问题讨论】:

【参考方案1】:

您发布的代码与您预期的含义不同。您将AnyObject 视为泛型类型,将UIPickerViewDataSourceUIPickerViewDelegate 作为类型参数。这与使用Int 键和String 值创建Dictionary 相同,例如:

var someDictionary: Dictionary<Int, String>

您要完成的工作需要一个不同的结构,称为协议组合。 Swift 专门提供它来表达符合多种协议的类型。它的语法如下,你可以在任何可以使用常规类型的地方使用它:

FirstProtocol & SecondProtocol

使用此功能,您的代码将变为:

// The typealias definition
typealias CellDelegate = UIPickerViewDataSource & UIPickerViewDelegate

// In my UITableViewCell subclass:
weak var delegate: CellDelegate?

Apple 的 Swift 语言指南here 中解释了协议组合。

编辑:已更新为 Swift 3 语法,感谢@raginmari

【讨论】:

在 Swift 3 中,语法已更改为 typealias CellDelegate = UIPickerViewDataSource &amp; UIPickerViewDelegate【参考方案2】:

如果要声明多协议:

protocol<A, B>

【讨论】:

【参考方案3】:

在 Swift 3 中,语法发生了变化。

在 Swift 2.3 之前: typealias CellDelegate = protocol<UIPickerViewDataSource, UIPickerViewDelegate>

从 Swift 3 开始: typealias CellDelegate = UIPickerViewDataSource & UIPickerViewDelegate

【讨论】:

【参考方案4】:

我不明白你为什么这样输入weak var delegate: &lt;CellDelegate&gt;?以及你为什么不输入weak var delegate: CellDelegate?

问题在于 AnyObject 是通用的。在第一行中,您尝试使 AnyObject 非泛型,但事实并非如此。

你最好创建一个类来实现这些(数据源和委托)。

【讨论】:

啊,尖括号——我只是忘了把它们从我想要的 typealias 中删除。 AnyObject 不是泛型类型,它实际上是所有类都遵循的协议,编译器错误就是这么说的:“Cannot specialise the non-generic type 任何对象"【参考方案5】:

你应该传递一个已知的对象,AnyObejct 太通用了,所以你不能这样做

【讨论】:

以上是关于为实现多个协议的任何对象定义一个 Swift 类型别名的主要内容,如果未能解决你的问题,请参考以下文章

Swift 同时将对象转换为类型和协议

swift 协议,IBOutlet 属性不能有非对象类型

协议作为 swift 冲突中的参数类型

swift protocol(协议) associatedtype关联类型

swift 学习- 24 -- 协议 01

将符合多个协议的类型转换为单个协议