Swift:iVar + Equatable 上的协议约束

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

背景

考虑 Swift 5.9 中的这个协议和类:

protocol SpinnerHosting: AnyObject
{
    var spinnerItem: SpinnerItem { get }
}
final class MyViewController: NSViewController
{
    var activeChild: (NSViewController & SpinnerHosting)? = nil

    
    func pushChild(_ incomingChild: (NSViewController & SpinnerHosting))
    {
        // #1
        if incomingChild != activeChild {
           ...
        }

        // #2
        if incomingChild != activeChild! {
           ...
        }
    }
}

问题

在第 1 点,Swift 抛出了这个错误:

Type 'any NSViewController & SpinnerHosting' cannot conform to 'Equatable'

在第 2 点(忽略不安全的展开)它会抛出这个:

Binary operator '!=' cannot be applied to two 'any NSViewController & SpinnerHosting' operands 

问题:

我明白为什么协议不是

Equatable
。但我不明白为什么编译器认为这不是。在这里,
SpinnerHosting
被限制为
AnyObject
,这意味着引用类型,因此意味着指针相等。但是,如果我将协议限制为
NSViewController
本身,同样的错误仍然存在,这 绝对 让我感到惊讶,因为
NSViewController
是相等的。

我只是想说:“无论

NSViewController
占据
activeChild
,都必须具有
spinnerItem
属性。” (我意识到我可以用子类来做到这一点;这不是我的问题。)

我刚刚在几个 Apple 源示例中看到了这种模式:

var foo: ([Class] & [Protocol])
,但我没有看到为什么这不能是
Equatable
的充分理由。

swift protocols nsviewcontroller equatable
1个回答
0
投票

所有引用类型都“与

==
一起使用”来比较指针,这是真的,但并非所有引用类型都声明与
Equatable
一致。

编译器不会通过查找协议声明的所有方法、属性和运算符来检查一致性;它只是检查声明的类型是否是协议或符合协议。

换句话说,即使类型有运算符

==
,也不意味着它可以转换为
Equatable
:必须显式声明一致性。

© www.soinside.com 2019 - 2024. All rights reserved.