首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有where子句的Swift数组扩展不适用于子协议

具有where子句的Swift数组扩展不适用于子协议
EN

Stack Overflow用户
提问于 2015-07-29 20:44:18
回答 2查看 803关注 0票数 1

我编写了一些我认为应该在Swift 2 (Xcode 7b4)中工作的代码,但它没有编译。我希望能思考一下我想要做的事情是否应该是有效的。

考虑下面的示例Array扩展:

代码语言:javascript
复制
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的同构类型需求(通过EquatableSelf的使用)。

如果我现在定义协议P和实现P的类C

代码语言:javascript
复制
protocol P : AnyObject {}

class C : P {}

并实例化一个C

let c = C()

那么,这些非常明显的事情是真的:

代码语言:javascript
复制
let cIsAnyObject = c as AnyObject   // ok
let cIsP = c as P                   // ok

我现在可以做以下几件事:

代码语言:javascript
复制
var a1 = [AnyObject]()              // []

a1.appendUniqueInstance(c)          // [c]
a1.appendUniqueInstance(c)          // [c]

到目前为止,还不错,但现在是问题案例:

代码语言:javascript
复制
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,这不是我想要的。

所以,在这一切之后,我的问题是:这看上去像是应该起作用的东西吗?我希望这不仅仅是声明语法错误的情况,但我想如果是这样的话,我会很高兴的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-02-26 17:44:06

在我编写原始问题时,编译器报告的错误似乎只是误导,而且我试图获得的功能没有(而且仍然没有)得到Swift的支持。

使用Xcode 8.2.1和Swift 3报告了一个更准确的错误:

代码语言:javascript
复制
// error: using 'P' as a concrete type conforming
//   to protocol 'AnyObject' is not supported
a2.appendUniqueInstance(c)
票数 0
EN

Stack Overflow用户

发布于 2016-02-09 15:39:52

如果命令单击AnyObject,您会注意到它是一个符合@objc的协议。因此,我猜这就是它要求使用@objc的原因。我注意到,如果我们将C作为NSObject的子类,则不需要显式地使来自P的方法的实现符合@objc

代码语言:javascript
复制
@objc protocol P : AnyObject {
    func hey()
}

class C : NSObject, P {
    func hey() {
        print("hey")
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31710737

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档