0Day Forums
Protocol doesn't support the "===" operator? - Printable Version

+- 0Day Forums (https://0day.red)
+-- Forum: Coding (https://0day.red/Forum-Coding)
+--- Forum: Swift (https://0day.red/Forum-Swift)
+--- Thread: Protocol doesn't support the "===" operator? (/Thread-Protocol-doesn-39-t-support-the-quot-quot-operator)



Protocol doesn't support the "===" operator? - disoblige769381 - 07-18-2023

It seems that `protocol` doesn't support the `===` operator, while `class` does.

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'

I think it could probably caused by the fact that the concrete type that conforms to the protocol could also be a value type (like `struct`) which doesn't support the `===` operator.
I'm just wondering that if I'm sure the real type is a class, how can I compare the references of them, like the `p1` and `p2` here?


RE: Protocol doesn't support the "===" operator? - breadfruitsv - 07-18-2023

Conform the protocol to either `class` or `AnyObject`
This means that **only classes** will be able to conform to that protocol, not struct.

For example, from:

protocol P {
}

to (*Swift 4 version*)

protocol P : AnyObject {
}

or (*Swift 3 version*)

protocol P : class {
}


RE: Protocol doesn't support the "===" operator? - health595202 - 07-18-2023

## **Equality between protocols**

Drop this in playground and your on your way.

protocol IPositional:class{}
class A:IPositional{}
class B:IPositional{}
let a:IPositional = A()
let b:IPositional = B()
let c:IPositional = a
a === b //false
a === c //true



RE: Protocol doesn't support the "===" operator? - sheryeoofcorve - 07-18-2023

First let's look at the definition of the `===` operator. It isn't just a test of equality between the value of two instances, but it checks to see if two variables point to the *exact same instance* of an object ([see "Identity Operators" here](

[To see links please register here]

)).

So your example code isn't quite right:

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

Only classes can be compared in this way, because everything that isn't a class in Swift is value-typed*, and two value-typed variables can't possibly be pointing to the same instance.

Therefore, if you try to compare a regular protocol with `===`, Swift doesn't have enough information to use the operator. The instances you're comparing (`p1` and `p2`) could be class instances or they could be struct instances, and at *compile-time* Swift can't tell if it's okay.

If you want to be able to use a protocol as a type in this way *and* compare with `===`, you'll need to declare a *class-only protocol* by using `class` as the first item in your protocol's inheritance list, like this:

protocol P : class {
}

class A : P {
}

Now you can do what you were attempting, without the compiler error:

var p1:P = a1
var p2:P = a2
var p3:P = a3
p1 === p2 // false
p2 === p3 // true

---

*Semantically, anyway. Swift does a lot of behind-the-scenes reference-typing, but enforces this value-typed behavior, so for the purposes of this discussion just go with `struct` and `enum` being truly value-typed.