我编写了一些我认为应该在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和实现P的类C
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 (通过P)是一个AnyObject。
顺便说一句,如果我将P声明为:
@objc protocol P : AnyObject {}
然后一切都编译得很好,但我还必须确保协议P中的所有内容都符合@objc,这不是我想要的。
所以,在这一切之后,我的问题是:这看上去像是应该起作用的东西吗?我希望这不仅仅是声明语法错误的情况,但我想如果是这样的话,我会很高兴的。
发布于 2017-02-26 17:44:06
在我编写原始问题时,编译器报告的错误似乎只是误导,而且我试图获得的功能没有(而且仍然没有)得到Swift的支持。
使用Xcode 8.2.1和Swift 3报告了一个更准确的错误:
// error: using 'P' as a concrete type conforming
// to protocol 'AnyObject' is not supported
a2.appendUniqueInstance(c)发布于 2016-02-09 15:39:52
如果命令单击AnyObject,您会注意到它是一个符合@objc的协议。因此,我猜这就是它要求使用@objc的原因。我注意到,如果我们将C作为NSObject的子类,则不需要显式地使来自P的方法的实现符合@objc
@objc protocol P : AnyObject {
func hey()
}
class C : NSObject, P {
func hey() {
print("hey")
}
}https://stackoverflow.com/questions/31710737
复制相似问题