Group Group Group Group Group Group Group Group Group

Chapter 13 - Object identity :Question about === operator


#1

Hi,
having read your explains about the === operator, I do not understand why this code :
class MyClass {
let id: Int
var linkedObject: MyClass?
init (id:Int) { self .id = id }
}

var x = MyClass(id: 1)
var y = MyClass(id: 2)

x.linkedObject = y
y.linkedObject = x
var z = x.linkedObject?.linkedObject

print(“Even if x is of type (type(of: x)) and z of type (type(of: z))”,terminator: ", ")
if x === z { print (“x and z are supposed to be the same thing !”) }
print( “Could you explain where does it comes from ?”)

produces its output :
Even if x is of type MyClass and z of type Optional<MyClass>, x and z are supposed to be the same thing !
Could you explain where does it comes from ?

Thank you by advance.


#2

@meaulnes You can break the following line of code:

var z = x.linkedObject?.linkedObject

into steps to understand better what’s going on exactly over here:

var t = x.linkedObject // y
var z = t?.linkedObject // x

After the first line of code, t is the same as y, so t === y returns true.

After the second line of code, z is the same as x, so z === x returns true.

Please let me know if you have any other questions or issues about the whole thing. Thank you!


#3

@shogunkaramazov, thank you for your answer but it does not exactly reply to my point which is :
I declared the property linkedObject as an optional so x.linkedObject?.linkedObject is not an instance of MyClass but an optional and there is no explicit unwrapping request for it ( something like x.linkedObject?.linkedObject! ) nevertheless the === operator seems to prove there is an implicit one.
Am I right or is there something I misunderstood ?
And if I am right what is the rational for this implicit unwrapping ?


#4

x.linkedObject?.linkedObject is an instance of MyClass, unless it is nil. Optional doesn’t change the type.

More to the point, both x and linkedObject are reference variables, which refer to an instance of an object. The comparison is of the objects referred to by the variables, not the variables themselves.

Here is a case of of a variable of class Foo being assigned to an instance of class Bar, which inherits from class Foo. Even though the reference variables are of different type, they can both end up referring to the same object, hence === will be true.

class Foo {
  let Foo_ness = "Foo"
}
class Bar: Foo {
  let Bar_ness = "Bar"
}

var testA: Foo = Foo()
var testB: Bar = Bar()
print ("1. testA === testB: \(testA === testB)")

testA = testB
print ("2. testA === testB: \(testA === testB)")

This prints out:

1. testA === testB: false

2. testA === testB: true

The testB object can function as a Foo or a Bar, but it is still the same object.


#5

Crystal clear @sgerrard ! Thank you.
I missed refer to.
I understand it implies for an optional to be unwrapped in order to determine what it refers to.