Swift扩展类型约束

问题描述 投票:1回答:1

XCode 11.2.1macOS Mojave 10.14.6

因此,如果我保留了引用,我将尝试添加从数组中删除对象的功能。根据Internet的建议,我使我的协议继承自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不承认这一点?

ios swift xcode compiler-errors extension-methods
1个回答
0
投票

您正在使用旧软件,因此不会收到现代错误消息:

引用'Array'上的实例方法'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]
© www.soinside.com 2019 - 2024. All rights reserved.