XCode 11.2.1
macOS Mojave 10.14.6
因此,如果我保留了引用,我将尝试添加从数组中删除对象的功能。遵循互联网的建议,我使我的协议继承自AnyObject
,因为这导致/要求/暗示===
在实现该协议的任何类上进行定义。但是,XCode与Array扩展上的类型的行为很奇怪。考虑以下编译是否正确:
public protocol Foo: AnyObject {
}
public extension Array where Element == Foo {
mutating func removeElement(element: Element) {
if let idx = self.firstIndex(where: {$0 === element}) {
self.remove(at: idx)
}
}
}
public func bar(array: [Foo], element: Foo) -> [Foo] {
var arrayCopy: [Foo] = array
arrayCopy.removeElement(element: element)
return arrayCopy
}
但是如果我将扩展名类型更改为Element: AnyObject
,则会出现如下编译错误:
...
public extension Array where Element: AnyObject {
...
...
// Compiler error: '[Foo]' requires that 'Foo' conform to 'AnyObject'
arrayCopy.removeElement(element: element)
...
Foo
符合AnyObject
。它的定义就在那里。为什么XCode不承认这一点?
答案 0 :(得分:0)
您使用的是旧软件,因此您不会收到现代错误消息:
在“数组”上引用实例方法“ removeElement(element :)” 要求“ Foo”为类类型
是的。据编译器了解,element
不是静态类型的实例,但是如果您这样编写它,它将是:
public func bar<Foo: Module.Foo>(array: [Foo], element: Foo) -> [Foo] {
其中Module
当然是模块的实际名称。
如果您需要使用异构数组,那么我不知道如何使事情更清洁。如果您想得更好,请告诉我。
(使函数的签名保持不变;请更改正文。)
var arrayCopy: [AnyObject] = array
arrayCopy.removeElement(element: element)
return arrayCopy as! [Foo]