Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 141 Vote(s) - 3.65 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Protocol doesn't support the "===" operator?

#1
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?
Reply

#2
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 {
}
Reply

#3
## **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
Reply

#4
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.


Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through