Home > database >  Why do Swift operator overloads need to be type methods?
Why do Swift operator overloads need to be type methods?

Time:10-14

The Swift Language Guide shows that operator methods like the following must be written as static:

struct Vector2D {
    var x = 0.0, y = 0.0
}

extension Vector2D {
    static func   (left: Vector2D, right: Vector2D) -> Vector2D {
        return Vector2D(x: left.x   right.x, y: left.y   right.y)
    }
}

let vector = Vector2D(x: 3.0, y: 1.0)
let anotherVector = Vector2D(x: 2.0, y: 4.0)
let combinedVector = vector   anotherVector

If you remove the static keyword, it will cause a compile error:

Operator ' ' declared in extension of 'Vector2D' must be 'static'

What is the reason for this requirement? Why can't we write this as a non-static method?

I could blindly accept that "this is just the way it's done". But I'd like to understand why this is necessary, so that I might understand the Swift language better. I have not been able to find a specific reason for this requirement.

If I had to guess, I'd guess that the default operators in Swift are implemented as type methods, and so our custom operators must likewise be static. But this is pure speculation.

CodePudding user response:

It makes perfect sense to me. A binary operator takes 2 objects as parameters, and returns a result.

Such an operator does not belong to an instance of any object. It is a static method on the class. For your example of the method for the Vector2D type, it is a method that knows how to add 2 Vector2D objects together.

You don't call the method on an instance of Vector2D. You say "Hey, Vector2D type, how do I add together two instances of your type?.

You are "talking to" the class, not an instance of the class.

CodePudding user response:

This is a language design choice, and different languages decided on opposites: C won't allow static operators, while C# requires them to be static, just like Swift.

To me the most compelling reason to have operators static is a symmetry.

Lets for a moment replace with function called plus. If plus is static, you'd call it as Vector2D.plus(vector, anotherVector), which will be the same as calling Vector2D.plus(anotherVector, vector).

If it was an instance member, you'd call it as vector.plus(anotherVector), which may or may not be the same as anotherVector.plus(vector). I.e. if vector is nil, the vector.plus(anotherVector) will definitely be nil, while anotherVector.plus(vector) will be equal to anotherVector.

Similarly, the operator being static allows that vector anotherVector == anotherVector vector, regardless of nil status of both vectors.

  • Related