Operator overloading not yet supported?
Asked Answered
O

2

18

According to the Swift Programming Guide, operator overloading is allowed and actually quite versatile. However, I have been unable to get it working in the playground.

For example, the Equatable protocol wants this: func ==(lhs:Self, rhs:Self) -> Bool

Let's say I make a simple Location3D struct:

struct Location3D
{
    var x : Double
    var y : Double
    var z : Double
}

Now I want this Location3D to implement the Equatable protocol, so I add it along with this method:

func ==(lhs: Self, rhs: Self) -> Bool
{
    return lhs.x == rhs.x &&
           lhs.y == rhs.y &&
           lhs.z == rhs.z
}

I get the compiler error of operators are only allowed at global scope. Huh?

So I tried adding @infix to the function, moving the function to an extension, changing the type to a class instead... all to no avail.

Am I missing something? How are you supposed to implement Equtable and Comparable when operators don't seem to work?

Ourselves answered 10/6, 2014 at 18:14 Comment(1)
global scope would point to a location outside of any Class or extension declarationJene
C
41

You need to override the == operator in the global scope but with your type for the arguments.

In this case it means you declare your struct to conform to the protocol and then simply implement the function outside it's scope.

struct Location3D : Equatable {
    // ...
}

func ==(lhs: Location3D, rhs: Location3D) -> Bool {
    // ...
}

See the library reference for further discussion:

https://developer.apple.com/documentation/swift/equatable

Coley answered 10/6, 2014 at 18:26 Comment(3)
I wonder why Apple would make it so unintuitive. If you are overloading an operator for a given class, why impose this restriction? It makes sense to have the operator func defined inside the class definition, like the other methods.Shieh
Note that if the struct is within a class, the operator overload has to go outside of the scope of the class as well (truly global scope).Araminta
== is infix operator, When overriding we don't need to specify it, right ?Sachet
Z
0

Since the original question was posted ten years ago and Swift might have changed in the meantime, I will pitch in. Once you add conformance to the Swift standard library’s Equatable protocol you can provide an implementation of the == operator in the same way as you implement other infix operators:

extension Location3D: Equatable {
    static func == (left: Location3D, right: Location3D) -> Bool {
       return (left.x == right.x) && (left.y == right.y) && (left.z == right.z) 
    }
}

It is not necessary to be in a global scope.
I hope this helps. More info can be found in the docs under advancedoperators

Zamboanga answered 26/6 at 14:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.