如何定义符合协议的对象数组?

时间:2014-10-24 06:13:23

标签: ios cocoa-touch swift

假设:

protocol MyProtocol {
    typealias T
    var abc: T { get }
}

实现MyProtocol的类:

class XYZ: MyProtocol {
    typealias T = SomeObject
    var abc: T { /* Implementation */ }
}

如何定义符合MyProtocol的对象数组?

var list = [MyProtocol]()

给出(连同大量的SourceKit崩溃)以下错误:

Protocol 'MyProtocol' can only be used as a generic constraint because it has Self or associated type requirements

即使实际上在MyProtocol中定义了类型。

有没有办法让对象列表符合协议并具有通用约束?

1 个答案:

答案 0 :(得分:3)

问题在于使用泛型对应的协议,键入别名。 这听起来很奇怪,但是如果你定义了一个类型别名,你就不能将协议用作一个类型,这意味着你不能声明那个协议类型的变量,一个函数参数等。你不能将它用作一个通用对象。阵列。

正如错误所说,您可以使用它的唯一用法是作为通用约束(如class Test<T:ProtocolWithAlias>中所示)。

要证明这一点,只需从协议中删除类型(注意,这只是为了证明,它不是解决方案):

protocol MyProtocol {
    var abc: Int { get }
}

并相应地修改其余的示例代码:

class XYZ: MyProtocol {
    var abc: Int { return  32 }
}

var list = [MyProtocol]()

你会注意到它有效。

您可能对如何解决此问题更感兴趣。我无法想到任何优雅的解决方案,只需以下2:

  • 从协议中删除typealias并将T替换为AnyObject(丑陋的解决方案!!)
  • 将协议转变为一个类(但这不是一个适用于所有情况的解决方案)

但你可能会说,我不喜欢他们中的任何一个。我能提供的唯一建议是重新考虑你的设计并弄清楚你是否可以使用不同的方式(即不使用typealased协议)来获得相同的结果。