斯威夫特3:有没有一种方法可以将对象同时转换为类和协议? [英] Swift 3: Is there a way to cast an object to a class and protocol at the same time?

查看:91
本文介绍了斯威夫特3:有没有一种方法可以将对象同时转换为类和协议?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了Apple Swift iBook的相关部分(类型转换和协议),但似乎可以找到一种方法来指定对象是符合特定协议的特定类的实例.

I've read through the relevant sections of Apple's Swift iBook (Type Casting & Protocols) but I can seem to find a way to specify that an object is an instance of a particular class that conforms to a specific protocol.

作为tableView(_: , cellForRowAt: )中的示例,我想将tableView.dequeueReusableCell(withIdentifier: reuseID, for: indexPath)返回的单元格转换为符合RLMEntityCapableCell协议的UITableViewCell的子类(只需指定遵循者具有称为item的变量)是Object或其子类之一的实例.

As an example in tableView(_: , cellForRowAt: ) I would like to cast the cell returned by tableView.dequeueReusableCell(withIdentifier: reuseID, for: indexPath) as being a subclass of UITableViewCell that conforms to the RLMEntityCapableCell protocol (Just specifies that conformers have a variable called item that is an instance of Object, or one of its subclasses).

这条路线可行,但双重铸造似乎过多:

This route works but the double casting seems excessive:

protocol RLMEntityCapableCell: class  {
     var item: Object { get set }
}

 public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    var cell = tableView.dequeueReusableCell(withIdentifier: reuseID, for: indexPath) as! RLMEntityCapableCell // Cast here so we can set item
    cell.item = items[indexPath.row]
    return cell as! UITableViewCell // Cast again so the return type is right…
}

另一种方法:

var cell = tableView.dequeueReusableCell(withIdentifier: reuseID, for: indexPath) 
           as! RLMEntityCapableCell, UITableViewCell

给出此错误:

模式中缺少

类型注释

type annotation missing in pattern

因此显然也不是正确的方法.

so clearly isn't the right way to do it either.

我更希望指定一个对象,以便遵守该协议,必须从UITableViewCellUICollectionViewCell继承,但是协议的基础只能限于类类型,而不能进一步限制.

I would prefer to specify that in order to conform to the protocol an object has to inherit from either UITableViewCell or UICollectionViewCell but the base of a protocol can only be limited to the class type and no further.

这里的想法是为Realm对象提供一个通用数据源,该资源像ArrayDictionary一样利用通用属性.每个表视图中使用的单元格将特定于要显示的实体,但是数据源将仅知道该单元格是UITableViewCell的子类,且符合RLMEntityCapableCell.所有数据源需要担心的是告诉单元它需要显示什么实例(该实例始终是Object的子类),单元会从那里获取它并根据需要对其进行配置.

The idea here is to have a generic data source for Realm objects that leverages generics much like Array and Dictionary do. The cells used in each table view would be specific to the entity to be displayed but the data source would only know that the cell would be a subclass of UITableViewCell that conforms to RLMEntityCapableCell. All the data source needs to worry about is telling the cell what instance (that would always be a subclass of Object) it needs to display, the cell would take it from there and configure itself as needed.

推荐答案

不,这不可能... .

No, this isn't possible... yet.

下一个Swift版本(版本4)可能会带来您想要的东西,一项名为

The next Swift release (version 4) might bring what you are looking for, a new feature called Class and Subtype Existentials:

该提案通过允许Swift表示符合符合协议的类和子类型的 existentials ,为类型系统带来了更多的表达力.

This proposal brings more expressive power to the type system by allowing Swift to represent existentials of classes and subtypes which conform to protocols.

该提案保留了现有的&语法,但允许其中一个元素为AnyObject或类类型(例如,SomeClass & SomeProtocol).

The proposal keeps the existing & syntax but allows one of the elements to be either AnyObject or of class type (e.g., SomeClass & SomeProtocol).

然后您可以说:

var cell = tableView.dequeueReusableCell(withIdentifier: reuseID, for: indexPath) 
           as! UITableViewCell & RLMEntityCapableCell

但是,当然,您将无法使用它为RLMEntityCapableCell协议添加超类要求(如您最初希望的那样).为此,我们可能需要等待Swift 5:)

But, of course, you won't be able to use this to add a superclass requirement to your RLMEntityCapableCell protocol (as you initially wished). We may need to wait for Swift 5 for that :)

使用上述 Class and Subtype Existentials (Swift 4)功能的其他一些示例:

Some other examples using the above Class and Subtype Existentials (Swift 4) feature:

protocol P {}
struct S {}
class C {}
class D : P {}
class E : C, P {}

let u: S & P // Compiler error: S is not of class type
let v: C & P = D() // Compiler error: D is not a subtype of C
let w: C & P = E() // Compiles successfully

和:

protocol P {}
class C {}
class D : C { }
class E : C { }
class F : D, P { }

let t: C & D & P = F() // Okay: F is a subclass of D and conforms to P
let u: D & P = t       // Okay: D & P is equivalent to C & D & P
let v: C & D & P = u   // Okay: C & D & P is equivalent to D & P
let w: D & E & P       // Compiler error: D is not a subclass of E or vice-versa

这篇关于斯威夫特3:有没有一种方法可以将对象同时转换为类和协议?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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