一尘不染

在Swift中,如何声明符合一种或多种协议的特定类型的变量?

swift

在Swift中,我可以通过声明如下来显式设置变量的类型:

var object: TYPE_NAME

如果我们想更进一步,并声明一个符合多种协议的变量,可以使用protocol声明式:

var object: protocol<ProtocolOne,ProtocolTwo>//etc

如果我想声明一个符合一个或多个协议并且也是特定基类类型的对象,该怎么办?等效的Objective-C看起来像这样:

NSSomething<ABCProtocolOne,ABCProtocolTwo> * object = ...;

在Swift中,我希望它看起来像这样:

var object: TYPE_NAME,ProtocolOne//etc

这使我们能够灵活处理基本类型的实现以及协议中定义的添加接口。

还有其他更明显的方式可能会让我丢失吗?

例如,假设我有一家UITableViewCell工厂负责返回符合协议的单元。我们可以轻松地设置一个泛型函数来返回符合协议的单元格:

class CellFactory {
    class func createCellForItem<T: UITableViewCell where T:MyProtocol >(item: SpecialItem,tableView: UITableView) -> T {
        //etc
    }
}

稍后我想在利用类型和协议的同时使这些单元出队

var cell: MyProtocol = CellFactory.createCellForItem(somethingAtIndexPath) as UITableViewCell

由于表视图单元格不符合协议,因此返回错误。

我想能够指定单元格是a UITableViewCell并符合MyProtocol变量声明中的?

理由

如果您熟悉工厂模式,那么在能够返回实现特定接口的特定类的对象的背景下,这将是有意义的。

就像在我的示例中一样,有时我们希望定义在应用于特定对象时有意义的接口。我关于表格视图单元格的示例就是这样一种证明。

尽管提供的类型与所提到的接口不完全一致,但是工厂返回的对象却与之一致,所以我希望在与基类类型和声明的协议接口交互时具有灵活性


阅读 308

收藏
2020-07-07

共1个答案

一尘不染

在Swift 4中,现在可以声明一个变量,该变量是类型的子类,并且可以同时实现一个或多个协议。

var myVariable: MyClass & MyProtocol & MySecondProtocol

要执行可选变量:

var myVariable: (MyClass & MyProtocol & MySecondProtocol)?

或作为方法的参数:

func shakeEm(controls: [UIControl & Shakeable]) {}

苹果在WWDC 2017
大会402上宣布了这一点:Swift的新增功能

第二,我想谈谈组成类和协议。因此,在这里,我为UI元素引入了这种可晃动的协议,该协议可以给人一点震动效果,从而引起人们的注意。而且,我继续并扩展了一些UIKit类,以实际提供此震动功能。现在,我想写一些看起来很简单的东西。我只想编写一个函数,该函数需要一堆可摇晃的控件,并摇晃那些能够引起人们注意的控件。我可以在此数组中写什么类型?这实际上是令人沮丧和棘手的。因此,我可以尝试使用UI控件。但并非所有UI控件在此游戏中都是可摇晃的。我可以尝试可Shakable,但并非所有可Shakable都是UI控件。实际上,在Swift
3中没有很好的方式来表示这一点。 Swift 4引入了用任意数量的协议组成一个类的概念。

2020-07-07