![]() |
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. |