我编写了一些我认为应该在 Swift 2 (Xcode 7b4) 中工作的代码,但它没有编译。我希望对我正在尝试做的事情是否有效有一些想法。
考虑这个示例Array
扩展:
extension Array where Element: AnyObject {
mutating func appendUniqueInstance(e: Element) {
for element in self {
if (element === e) {
return
}
}
self.append(e)
}
}
首先,元素为 的数组是什么意思AnyObject
?基本上我是说数组应该包含一组异构的非值类型对象,可以比较例如相等(===
)。
示例函数appendUniqueInstance()
仅将元素插入到数组中(如果它不在数组中)。这类似于Set
insert()
操作,但显然提供了排序并且(更重要的是)不强加Set
' 的同质类型要求(通过Equatable
' 的使用Self
)。
如果我现在定义一个协议P
和一个C
实现的类P
:
protocol P : AnyObject {}
class C : P {}
并实例化一个C
:
let c = C()
那么这些非常明显的事情是真的:
let cIsAnyObject = c as AnyObject // ok
let cIsP = c as P // ok
我现在可以执行以下操作:
var a1 = [AnyObject]() // []
a1.appendUniqueInstance(c) // [c]
a1.appendUniqueInstance(c) // [c]
到目前为止,一切都很好,但现在对于问题案例:
var a2 = [P]()
a2.append(c) // ok, -> [c]
// Compiler error: Cannot invoke 'appendUniqueInstance' with an argument list of type '(C)'
a2.appendUniqueInstance(c)
在这里,a2
被键入为 的数组,因此对的实例P
执行此操作应该是完全有效的,并且确实该行按我们预期的那样工作。append
P
a2.append(c)
然而,调用Array
扩展函数会appendUniqueInstance()
产生编译器错误。
据我所知,编译器似乎对可以传递的内容感到困惑,appendUniqueInstance()
而没有意识到(或由于某种原因允许)C
(via P
) 是一个AnyObject
.
顺便说一句,如果我P
改为声明:
@objc protocol P : AnyObject {}
然后一切都编译得很好,但我还必须确保协议中的所有内容都P
符合@objc
,这不是我想要的。
所以,在这一切之后,我的问题是:这看起来应该可行吗?我希望这不仅仅是一些声明语法错误的情况,但我想如果是这样我会很高兴。