在 Swift 中,如何声明符合一个或多个协议的特定类型的变量? [英] In Swift, how can I declare a variable of a specific type that conforms to one or more protocols?

查看:35
本文介绍了在 Swift 中,如何声明符合一个或多个协议的特定类型的变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In Swift I can explicitly set the type of a variable by declaring it as follows:

var object: TYPE_NAME

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

If we want to take it a step further and declare a variable that conforms to multiple protocols we can use the protocol declarative:

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

如果我想声明一个符合一个或多个协议并且也是特定基类类型的对象怎么办?等效的 Objective-C 如下所示:

What if I would like to declare an object that conforms to one or more protocols and is also of a specific base class type? The Objective-C equivalent would look like this:

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

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

In Swift I would expect it to look like this:

var object: TYPE_NAME,ProtocolOne//etc

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

This gives us the flexibility of being able to deal with the implementation of the base type as well as the added interface defined in the protocol.

还有其他更明显的方式我可能会遗漏吗?

Is there another more obvious way that I might be missing?

举个例子,假设我有一个 UITableViewCell 工厂,负责返回符合协议的单元格.我们可以轻松设置一个通用函数,返回符合协议的单元格:

As an example, say I have a UITableViewCell factory that is responsible for returning cells conforming to a protocol. We can easily setup a generic function that returns cells conforming to a protocol:

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

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

later on I want to dequeue these cells whilst leveraging both the type and the protocol

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

这会返回一个错误,因为表格视图单元格不符合协议...

This returns an error because a table view cell does not conform to the protocol...

我希望能够指定单元格是一个 UITableViewCell 并且符合变量声明中的 MyProtocol?

I would like to be able to specify that cell is a UITableViewCell and conforms to the MyProtocol in the variable declaration?

如果您熟悉工厂模式,这在能够返回实现特定接口的特定类的对象.

If you are familiar with the Factory Pattern this would make sense in the context of being able to return objects of a particular class that implement a certain interface.

就像在我的示例中一样,有时我们喜欢定义在应用于特定对象时有意义的接口.我的表格视图单元格示例就是这样一种理由.

Just like in my example, sometimes we like to define interfaces that make sense when applied to a particular object. My example of the table view cell is one such justification.

虽然提供的类型不完全符合上述接口,但工厂返回的对象符合,所以我希望与基类类型和声明的协议接口交互的灵活性

Whilst the supplied type does not exactly conform to the mentioned interface, the object the factory returns does and so I would like the flexibility in interacting with both the base class type and the declared protocol interface

推荐答案

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

In Swift 4 it is now possible to declare a variable that is a subclass of a type and implements one or more protocols at the same time.

var myVariable: MyClass & MyProtocol & MySecondProtocol

做一个可选变量:

var myVariable: (MyClass & MyProtocol & MySecondProtocol)?

或作为方法的参数:

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

Apple 在 WWDC 2017 的Session 402:Whats new in斯威夫特

Apple announced this at WWDC 2017 in Session 402: Whats new in Swift

其次,我想谈谈编写类和协议.所以在这里我已经为一个 UI 元素引入了这个可震动的协议,它可以提供有点摇晃效果来吸引注意力.我已经走了并扩展了一些 UIKit 类来实际提供这种震动功能.现在我想写一些看起来很简单的东西.一世只想写一个函数,它接受一堆控件摇动和摇动那些能够引起注意的他们.我可以在这个数组中写什么类型?其实是令人沮丧和棘手.所以,我可以尝试使用 UI 控件.但不是在这个游戏中所有的 UI 控件都是可动的.我可以尝试摇晃,但是并非所有可摇动都是 UI 控件.而且实际上没有什么好方法在 Swift 3 中表示这一点. Swift 4 引入了组合的概念具有任意数量协议的类.

Second, I want to talk about composing classes and protocols. So, here I've introduced this shakable protocol for a UI element that can give a little shake effect to draw attention to itself. And I've gone ahead and extended some of the UIKit classes to actually provide this shake functionality. And now I want to write something that seems simple. I just want to write a function that takes a bunch of controls that are shakable and shakes the ones that are enabled to draw attention to them. What type can I write here in this array? It's actually frustrating and tricky. So, I could try to use a UI control. But not all UI controls are shakable in this game. I could try shakable, but not all shakables are UI controls. And there's actually no good way to represent this in Swift 3. Swift 4 introduces the notion of composing a class with any number of protocols.

这篇关于在 Swift 中,如何声明符合一个或多个协议的特定类型的变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆