错误提示"冗余的约束'Self' : 'AnyObject'" - `AnyObject`在哪里?

4

在我开发过程中(我使用的是Swift 4.1),我遇到了一个奇怪的Swift编译器消息:

protocol Foo: class where Self: NSObject { // (1)
    // Redundant constraint 'Self' : 'AnyObject'
}

这里正在发生什么?
首先,这并不是多余的。当我写下这句话时,
protocol Foo: class { } // (2)

我有一个协议,任何对象都可以潜在地符合它,即使是不从 NSObject 派生的对象。但是我可以创建弱引用:weak var f: Foo? 是可以的。

另一方面,当我写下

protocol Foo where Self: NSObject { } // (3)

我有一个协议,无法生成弱引用:weak var f: Foo? 是编译时错误。
其次,AnyObject 是从哪里来的?我要求的是 NSObject。尽管尊重 NSObject:我无法声明一个 class MyFoo: Foo { },因为它正确地抱怨它必须继承自 NSObject
这是 Swift 的一个 bug 吗?还是我漏掉了什么?如果这是一个 bug:它是因为代码段(3)不让我使用弱引用吗?还是因为编译器警告?还是两者都有?如果我漏掉了什么:那是什么?

将协议限制为给定类并不是Swift完全支持的(实际上,它应该拒绝where Self: NSObject约束,直到它支持),请参见https://dev59.com/RFYO5IYBdhLWcg3wKemM#50647762。 - Hamish
@RobNapier:我对Swift泛型的当前状态有些沮丧。我应该停止在SO上问这个问题,并在2020年重新评估这些东西,等到Swift 5发布后再看看。现在,每次我尝试使用Swift进行泛型编程时,都会遭遇惨败。但是在Haskell、Objective C甚至C++中,只要按照语言规则组合类型,它们就能够更或多或少地按预期行事。据说,我们将在Swift 4.2中获得条件一致性;终于。与此同时,我将坚持使用非泛型代码。 - Michael
@RobNapier:我理解你的担忧。我90%的时间都是不使用泛型进行编程的。在尝试使用泛型之前,我会三思而后行,至少在Swift中是这样。但是,偶尔我会尝试以通用的方式去做一些事情:例如,我想要一个委托列表,而不仅仅是一个委托(可能应该称它们为“观察者”),并且我不想保留它们所有。因此,我决定创建一个WeakArray。 - Michael
让我们在聊天中继续这个讨论 - Rob Napier
@RobNapier 嗯,在Xcode 10b1或接近主版本的构建中,使用protocol Foo where Self : NSObject {}weak var f: Foo?无法编译,也不能像func takesAFoo(_ foo: Foo) { print(foo.superclass as Any) }那样。据我所知,这仍然是尚未完全实现的东西。 - Hamish
显示剩余4条评论
2个回答

2
在Swift 4.1中,无法将协议限制为特定类的子类。您可以从NSObjectProtocol继承Foo,这可能符合您的意图。
protocol Foo: NSObjectProtocol { 
    // ....
}

在Swift 4.2中,你所写的是合法的Swift代码,且符合你的预期。

1

来自Swift公共API:

public typealias AnyObject /// 所有类类型隐式遵循的协议。

因此,通过声明您的协议符合 class,它会自动符合 AnyObject


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接