似乎协议不支持===操作符,而类是。
protocol P { } class A : P { } var a1 = A() var a2 = A() var p1:P = a1 var p2:P = a2 a1 === a2 // true p1 === p2 // error: Type 'P' does not conform to protocol 'AnyObject'
我认为这可能是由于符合协议的具体类型也可能是不支持===操作符的值类型(如struct)。
我只是想知道如果我确定真正的类型是一个类,我如何比较它们的引用,如p1和p2这里?
首先看看===操作符的定义。它不仅仅是两个实例的值之间相等的测试,而是检查两个变量是否指向一个完全相同的对象实例(
see “Identity Operators” here)。
所以你的示例代码是不正确的:
var a1 = A() var a2 = A() var a3 = a2 a1 === a2 // actually false,a1 and a2 were instantiated separately a2 === a3 // true,because they are the same instance
只有这样,才能比较类,因为Swift中不是类的所有东西都是值类型*,而两个值类型的变量不可能指向同一个实例。
因此,如果您尝试将常规协议与===进行比较,则Swift没有足够的信息可以使用运算符。您要比较的实例(p1和p2)可以是类实例,也可以是结构体实例,在编译时,Swift不能判断是否可以。
如果您想要以这种方式使用协议作为类型并与===进行比较,则需要通过使用类作为协议继承列表中的第一项来声明一个仅限类的协议,如下所示:
protocol P : class { } class A : P { }
现在你可以做你正在尝试的,没有编译错误:
var p1:P = a1 var p2:P = a2 var p3:P = a3 p1 === p2 // false p2 === p3 // true
*语义上,无论如何Swift做了大量幕后参考打字,但是强制执行这个值类型的行为,所以为了讨论这个目的,刚刚结构化和枚举是真正的价值型的。