Triple equal sign (===) in Swift

The first time I saw the triple equal sign (===) I found it works the same as in Javascript and checks if values are exactly the same but it works a little bit different.

By default double equal sign (==) compares two instances using Equatable protocol and instances must implement it.

However, triple equal sing (===) works differently. It checks if two instances of classes are the same comparing pointers.

Let’s say you have some Person class that has the name property.

class Person {
    
var name: String

    
init(name: String) {
    
    self.name = name
    }
}

And you create some instances, let’s say two Toms and one John.

let tom = Person(name: “Tom”)
let tom2 = Person(name: “Tom”)
let john = Person(name: “John”)

Both Toms have the same name value so they should be equal but there are different instances so === returns false.

if tom === tom {
    
print(“Tom is equal self”)
}

if tom === tom2 {
    
print(“Toms are equal”)
}
else {
    
print(“Toms aren’t equal”)
}

if tom !== john {
    
print(“Tom isn’t equal John”)
}

Output

Tom is equal self
Toms aren’t equal
Tom isn’t equal John

tom === tom is true because it’s the same instance.
tom === tom2 isn’t true because they are different instances even if they have to save name value.
tom !== john is true because they are different instances. Notice there is negation !==.

Let’s implement Equatable protocol and see difference between == and ===.

Now Person class looks like:

class Person: Equatable {
    var name:
String

    init(name:
String) {
        
self.name = name
    }

    
static func ==(lhs: Person, rhs: Person) -> Bool {
        
return lhs.name == rhs.name
    }
}

Now, use the same ifs but with a double equal sign (==).

if tom == tom {
    
print(“Tom is equal self”)
}

if tom == tom2 {
    
print(“Toms are equal”)
}
else {
    
print(“Toms aren’t equal”)
}

if tom != john {
    
print(“Tom isn’t equal John”)
}

Output

Tom is equal self
Toms are equal
Tom isn’t equal John

The first and third results are the same as expected. However, the second result is different and Toms are equal because names are equal.

Notice that you can override defuault behaviour of triple equls sing (===) doing something like this:

static func ===(lhs: Person, rhs: Person) -> Bool {
    
return lhs.name == rhs.name
}

But you have to answer yourself if you’re sure you want to do it especially when you work in a team and you change some default behavior.