How to create custom operators and do operators overloading in Swift

What is the operator.

An operator is a special symbol that you use with one or more values to produce a specific result. For example, the addition operator (+) adds two numbers and resulting in the sum between those two, as in let i = 1 + 2 .

You can think of it as a function with a unique name that can call in unusual places such as front, between, and after the value. You will see in the later section how creating a custom operator is similar to creating a function.

Before we begin to override or create a custom operator, let's learn how many types of operators we have in Swift. Which one that we can override and some limitation when we want to create a custom one.

You can easily support sarunw.com by checking out this sponsor.

Screenshot Studio:

Screenshot Studio: Create App Store screenshots in seconds not minutes.

Types of operators

We can categorize operators into three groups. Unary operators Binary operators Ternary operators

Unary operators

Unary operators operate on a single target such as -1, !booleanValue. Unary can appear in two places.

  • Unary prefix operators which appear immediately before their targets such as negative value ( -2 ) and logical not operator ( !booleanValue ).
  • Unary postfix operators which appear immediately after their target such as force unwrapping ( optionalValue! ).

We can overload and create a custom prefix and postfix operator.

Binary operators

Binary operators operate on two targets (such as 2 + 3). It can only appear in between their two targets, infix operator .

We can overload and create a custom infix operator.

Ternary operators

Ternary operators operate on three targets, such as the ternary conditional operator (a ? b : c).

We can't overload or create this kind of operator.

Not every type of operator can be overload. There are four restrictions that I know of:

  • You can't overload and create a custom ternary operator.
  • You can't overload the default assignment operator ( = ). You can overload other binary operators, including compound assignment operators such as a += 2.
  • Only a subset of the ASCII characters are supported. You can check the full list here .
  • Some characters and combinations are reserved for some operators. You can check the full list here .

Since we can't overload or create ternary operators, that left us with three kinds of operators to play with: Prefix Postfix Infix

Now that we know its limitation, let's try overloading existing operators, then defining your own.

Overloading the existing operators

Operator overloading lets us declare multiple operators of the same name with different implementations, in this case, different operands [1] and return type.

Let's start with overloading infix operators.

Overload new operator on strings

Swift supports the four standard arithmetic operators for all number types:

  • Addition (+)
  • Subtraction (-)
  • Multiplication (*)
  • Division (/)

Swift string doesn't support the * operator, but we will overload the * operator to work on it. We will overload the * operator to take string and integer as arguments and produce a new string representing the given string repeated the specified number of times. The result will look like this:

As I mentioned before, you can think of operators as a function with a special name. To declare overloading operators, we would do just that.

Declare as a global function You can declare it as a global function like this.

Declare as static function of a class or struct You can declare it as a static function under a class or struct. I prefer this form since it shows that the operator is a part of string capability (This is also how Swift declare the + operator on the string)

<1> We declare an infix operator that works on two operands, string, and integer, and returns a new string. <2> We create a new string representing the given string repeated the specified number of times.

Again, here is the result:

Overload existing operators with different arguments.

Swift string already overloading + operators, which concatenated two strings together.

We will overload the + operator with a different argument. Our new overloading operates on string and integer and produces a string with the last character repeated equals to the second operands.

<1> Try to get the last character. <2> Concatenate the string with the repeated last character.

To overloading a prefix operator, we need to add a prefix keyword before a func .

In the following example, I overload the - unary operator for a string, which will reverse the characters in a given string.

<1> We add the prefix keyword to tell the compiler that this is intended to use as a prefix operator.

And here is the result:

To overloading a postfix operator, we need to add a postfix keyword before a func .

In the following example, I overload ... unary operator for string which will append "..." string at the end of the given string.

<1> We add the postfix keyword to tell the compiler that this is intended to use as a postfix operator.

Adding a custom operator

If the existing operators are not enough for you, Swift allows you to define a new operator. We will create a new operator called 🩄 Unicorn operator ( .^. ). Then we will make this operator operate on a string. The unicorn operator will insert a rainbow emoji đŸłïžâ€đŸŒˆ according to the operation position (prefix, postfix, infix).

The first thing we need to do is telling Swift about our new operator. We will start with the infix version of our Unicorn operator.

This is a syntax to declare a new infix operator.

That's all we need to do. Now Swift knows about our new operator. We can use it the same way as we did with operator overloading.

<1> We overload our new operator with string operands. <2> Our Unicorn operator will insert a rainbow flag between two operands.

It is not much different on how to declare an infix operator. The only difference we need to make is changing the keyword from infix to postfix .

This is a syntax to declare a new postfix operator.

Then we use it just like before.

<1> We append a rainbow flag at the end of the string.

You might be able to guess. Here is how we declare a new prefix operator.

And here is how we implement it.

<1> We prepend a rainbow flag at the beginning of the string.

The difference between overload existing operator and a custom one

As you can see, the only difference between an overload existing operator and a custom one is declaring a new operator . If you are failing to do so, the compiler will give you this error.

Operator implementation without matching operator declaration error

It might be debatable about this Swift feature whether you should use it or not. In the end, it all about trades off. Using this feature would save you from some boilerplate code but might cause poor code readability since you introduce a new syntax and implementation to the existing operators. I think you would find a fair use case out of it when the time comes.

I also leave out some implementation detail of declaring a new operator, Operator Precedence and Associativity. I think it deserves its own article and I might write about it in the future. If you don't want to miss it, Subscribe or Follow me on Twitter and get notified.

Related Resourcess

  • Advanced Operators
  • Lexical Structure - Operators , List of characters that can be used to define custom operators.
  • Operator Declarations

The values that operators affect are operands . In the expression 1 + 2, the + symbol is a binary operator, and its two operands are the values 1 and 2. ↩

You may also like

  • Swift Ternary operator (?:) 09 Feb 2023
  • What does the ?? operator mean in Swift 30 Sep 2021
  • How to compare two app version strings in Swift 08 May 2020
  • How to check if String is Number in Swift 24 Sep 2022
  • How to read App Name, Version, and Build Number from Info.plist 17 May 2021
  • if let: How not to use it 02 Nov 2019

Enjoy the read?

If you enjoy this article, you can subscribe to the weekly newsletter. Every Friday , you'll get a quick recap of all articles and tips posted on this site . No strings attached. Unsubscribe anytime.

Feel free to follow me on Twitter and ask your questions related to this post. Thanks for reading and see you next time.

If you enjoy my writing, please check out my Patreon https://www.patreon.com/sarunw and become my supporter. Sharing the article is also greatly appreciated.

Part 2 in the series "Building Lists and Navigation in SwiftUI". We will explore a ScrollView, UIScrollView equivalent in SwiftUI.

Part 3 in the series "Building Lists and Navigation in SwiftUI". We will explore a List, UITableView equivalent in SwiftUI.

  • Sponsorship
  • Become a patron
  • Buy me a coffee
  • Privacy Policy

Overloading assignment operator

The ability to overload operators is very useful. However, that utility is diminished without the ability to overload the simple assignment operator ( = ). I vaguely recall reading somewhere that there is a reason for this having to do with syntax ambiguity. Can this problem be solved so that = can be overloaded?

Yes, I understand the concern you raise. I too have held that general opinion of overloading operators in other languages for many years. That said, overloading arithmetic and other operators causes the same opportunity for abuse. For example, overloading + for integers to do something different (like rounding instead of truncation) would make maintenance of existing programs into a giant guessing game.

That said, once the cat is out of the bag to overload operators, I don't see how adding support for = makes things any worse.

FYI, the reason for my suggestion is to add support for fixed decimal arithmetic just like that available in COBOL. Yeh I can hear the groans now. However, for business applications, fixed decimal arithmetic is a basic feature that has been tossed away in new languages by language designers who don't actually labor in the trenches. I've built a simple class to do just that - here is some sample code that uses my Number class that gives an idea of what the code does:

var amount = Number(left: 6, right: 2); var result = Number(left: 9, right: 2); amount <- 3.9; amount += 1; result <- amount * 4; print(result)

Note that <- is the assignment operator. I am sure all would agree that = is superior in this situation. Such code would be far more readable and the Number values would act just like and interoperate with Float and Int in all regards *except* that currently the = operator is not available for assignment.

PS. FWIW, the IEEE 754-2008 d128 alternative that Chris Lattner mentioned to me is inferior to the kind of support for fixed decimal arithmetic that I believe would help make Swift superior to C# for business applications.

On Dec 6, 2015, at 6:58 AM, Silvan Mosberger <[email protected]> wrote: Hi Don I think this is a terrible idea! Imagine what you’d be able to do with that: let x : String = 3 This would lead to the same problems already discussed with implicit initialisers: [swift-evolution] Proposal: Auto-convert for numbers when safe , just worse. Also assignment is something more fundamental than other operators, I doubt it’s even possible to do that. On 06 Dec 2015, at 14:44, Don Wills via swift-evolution <[email protected] <mailto:[email protected]>> wrote: The ability to overload operators is very useful. However, that utility is diminished without the ability to overload the simple assignment operator ( = ). I vaguely recall reading somewhere that there is a reason for this having to do with syntax ambiguity. Can this problem be solved so that = can be overloaded? Don Wills _______________________________________________ swift-evolution mailing list [email protected] <mailto:[email protected]> https://lists.swift.org/mailman/listinfo/swift-evolution

In your specific case, I think Alex Lew is completely correct: you really don’t want a ton of overloaded operators, you just want your decimal type to be literal-convertible.

But to answer the question more generally, no, I can’t foresee us ever allowing the overloading of =, no. = always means simple initialization/assignment in Swift; that is, it always simply propagates values around. That’s a very fundamental language concept to mess around with.

The way to fix your problem in a less ad hoc way is to allow user-defined implicit conversions, which is something we’ve talked about already in a different thread. What I said there was that it will require a lot of very careful language/type-checker design work. Here, I’d like to identity another problem: the behavior of implicit conversions can be very confusing for non-experts to reason about, and in the context of a language with a fair amount of other subtle behaviors (e.g. due to overloading), that’s a very dangerous thing to bring in. Explicit type coercions are much easier for non-experts to reason about.

On Dec 6, 2015, at 5:44 AM, Don Wills via swift-evolution <[email protected]> wrote: The ability to overload operators is very useful. However, that utility is diminished without the ability to overload the simple assignment operator ( = ). I vaguely recall reading somewhere that there is a reason for this having to do with syntax ambiguity. Can this problem be solved so that = can be overloaded?

Don, have you considered making your Number type FloatLiteralConvertible? This would allow you not just to *let number: Number = 4.9*, but also pass in 4.9 to a function that expected a *Number*. It would not let you set Number variables to be equal to other variables of type Float, it seems your main use case here is literals anyway.

On Sun, Dec 6, 2015 at 9:26 AM, Don Wills via swift-evolution < [email protected]> wrote:

Silvan, Yes, I understand the concern you raise. I too have held that general opinion of overloading operators in other languages for many years. That said, overloading arithmetic and other operators causes the same opportunity for abuse. For example, overloading + for integers to do something different (like rounding instead of truncation) would make maintenance of existing programs into a giant guessing game. That said, once the cat is out of the bag to overload operators, I don't see how adding support for = makes things any worse. FYI, the reason for my suggestion is to add support for fixed decimal arithmetic just like that available in COBOL. Yeh I can hear the groans now. However, for business applications, fixed decimal arithmetic is a basic feature that has been tossed away in new languages by language designers who don't actually labor in the trenches. I've built a simple class to do just that - here is some sample code that uses my Number class that gives an idea of what the code does: var amount = Number(left: 6, right: 2); var result = Number(left: 9, right: 2); amount <- 3.9; amount += 1; result <- amount * 4; print(result) Note that <- is the assignment operator. I am sure all would agree that = is superior in this situation. Such code would be far more readable and the Number values would act just like and interoperate with Float and Int in all regards *except* that currently the = operator is not available for assignment. Don Wills PS. FWIW, the IEEE 754-2008 d128 alternative that Chris Lattner mentioned to me is inferior to the kind of support for fixed decimal arithmetic that I believe would help make Swift superior to C# for business applications. On Dec 6, 2015, at 6:58 AM, Silvan Mosberger < [email protected]> > wrote: Hi Don I think this is a terrible idea! Imagine what you’d be able to do with that: let x : String = 3 This would lead to the same problems already discussed with implicit initialisers: [swift-evolution] Proposal: Auto-convert for numbers when safe , just worse. Also assignment is something more fundamental than other operators, I doubt it’s even possible to do that. On 06 Dec 2015, at 14:44, Don Wills via swift-evolution < > [email protected]> wrote: The ability to overload operators is very useful. However, that utility is diminished without the ability to overload the simple assignment operator ( = ). I vaguely recall reading somewhere that there is a reason for this having to do with syntax ambiguity. Can this problem be solved so that = can be overloaded? Don Wills _______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution Untracked with Trackbuster < Your contacts automatically up to date | evercontact ; _______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution

Yes, I meant for the email to go to the list.

Nope, that doesn't work because of my comment above. That's the change

to Swift I am hoping will be adopted for 3.0.

Did you try this? The idea is to write a function for multiplying a Number and an Int, so the rhs will create a Number which will then be set to the variable. It should work actually.

On Mon, Dec 7, 2015 at 00:47 Don Wills <[email protected]> wrote:

Hello Ilya, On Dec 6, 2015, at 1:09 PM, ilya <[email protected]> wrote: On Sun, Dec 6, 2015 at 5:26 PM, Don Wills via swift-evolution < > [email protected]> wrote: Silvan, Yes, I understand the concern you raise. I too have held that general opinion of overloading operators in other languages for many years. That said, overloading arithmetic and other operators causes the same opportunity for abuse.

For example, overloading + for integers to do something different (like

rounding instead of truncation) would make maintenance of existing programs into a giant guessing game. That said, once the cat is out of the bag to overload operators, I don't see how adding support for = makes things any worse.

This is not really the same. You only use + explicitely, but the compiler must insert some assigments automatically, for example by copying when the function closes over some variables. It must know exactly what the semantics in this case is to be able to compile correct program.

My example wasn't the best. IMO, there is almost no conceptual difference between "amount = 5.5;" and "amount += 5.5;". The second example works (that is += can be overloaded) where the first example is not allowed because when I try to define the "func = (...) {...}" overload implementation, the compiler squawks.

FYI, the reason for my suggestion is to add support for fixed decimal

arithmetic just like that available in COBOL. Yeh I can hear the groans now.

I'm with you.

However, for business applications, fixed decimal arithmetic is a basic feature that has been tossed away in new languages by language designers who don't actually labor in the trenches.

I didn't look into the new Foundation, but doesn't it contain NSDecimalNumber?

I've built a simple class to do just that - here is some sample code that

uses my Number class that gives an idea of what the code does: var amount = Number(left: 6, right: 2); var result = Number(left: 9, right: 2); amount <- 3.9; amount += 1; result <- amount * 4; print(result)

I'm not sure why you feel the need to overload = in this example. If Number * Int -> Number is defined, you can just use

result = amount * 4

Nope, that doesn't work because of my comment above. That's the change to Swift I am hoping will be adopted for 3.0.

Did you mean to not post your email to me only? I haven't figured out the protocol for this email list yet.

On Dec 6, 2015, at 10:54 PM, John McCall <[email protected]> wrote: On Dec 6, 2015, at 5:44 AM, Don Wills via swift-evolution <[email protected]> wrote: The ability to overload operators is very useful. However, that utility is diminished without the ability to overload the simple assignment operator ( = ). I vaguely recall reading somewhere that there is a reason for this having to do with syntax ambiguity. Can this problem be solved so that = can be overloaded?

I guess I missed the subtlety that in Swift the statement "x = y;" is fundamentally different than "x += y;". That surprises me. And it fails one of the basic principles that I've always applied to software design: The Principle of Least Astonishment.

Thanks for your response, even though it is quite disheartening to me. As I get to know the nuances of Swift, I'm starting to think that moving to Swift might be too big of a stretch for my programming staff.

Here, I’d like to identity another problem: the behavior of implicit conversions can be very confusing for non-experts to reason about, and in the context of a language with a fair amount of other subtle behaviors (e.g. due to overloading), that’s a very dangerous thing to bring in. Explicit type coercions are much easier for non-experts to reason about.

+1 to this. I am very skeptical that the benefit of implicit conversions are worth the complexity and potential for confusion, except where a natural subtype relationship exists like Chris has mentioned in relation to numerics.

I think that his number assignment (via `<~`) depends on the current state of `amount`, and that using FloatLiteralConvertible does not provide enough information at the call site (since the current value is not available in the initializer).

On Dec 6, 2015, at 1:43 PM, Alex Lew via swift-evolution <[email protected]> wrote: Don, have you considered making your Number type FloatLiteralConvertible? This would allow you not just to let number: Number = 4.9, but also pass in 4.9 to a function that expected a Number. It would not let you set Number variables to be equal to other variables of type Float, it seems your main use case here is literals anyway. FloatLiteralConvertible — SwiftDoc.org On Sun, Dec 6, 2015 at 9:26 AM, Don Wills via swift-evolution <[email protected] <mailto:[email protected]>> wrote: Silvan, Yes, I understand the concern you raise. I too have held that general opinion of overloading operators in other languages for many years. That said, overloading arithmetic and other operators causes the same opportunity for abuse. For example, overloading + for integers to do something different (like rounding instead of truncation) would make maintenance of existing programs into a giant guessing game. That said, once the cat is out of the bag to overload operators, I don't see how adding support for = makes things any worse. FYI, the reason for my suggestion is to add support for fixed decimal arithmetic just like that available in COBOL. Yeh I can hear the groans now. However, for business applications, fixed decimal arithmetic is a basic feature that has been tossed away in new languages by language designers who don't actually labor in the trenches. I've built a simple class to do just that - here is some sample code that uses my Number class that gives an idea of what the code does: var amount = Number(left: 6, right: 2); var result = Number(left: 9, right: 2); amount <- 3.9; amount += 1; result <- amount * 4; print(result) Note that <- is the assignment operator. I am sure all would agree that = is superior in this situation. Such code would be far more readable and the Number values would act just like and interoperate with Float and Int in all regards *except* that currently the = operator is not available for assignment. Don Wills PS. FWIW, the IEEE 754-2008 d128 alternative that Chris Lattner mentioned to me is inferior to the kind of support for fixed decimal arithmetic that I believe would help make Swift superior to C# for business applications. On Dec 6, 2015, at 6:58 AM, Silvan Mosberger < [email protected] <mailto:[email protected]>> wrote: Hi Don I think this is a terrible idea! Imagine what you’d be able to do with that: let x : String = 3 This would lead to the same problems already discussed with implicit initialisers: [swift-evolution] Proposal: Auto-convert for numbers when safe , just worse. Also assignment is something more fundamental than other operators, I doubt it’s even possible to do that. On 06 Dec 2015, at 14:44, Don Wills via swift-evolution < [email protected] <mailto:[email protected]>> wrote: The ability to overload operators is very useful. However, that utility is diminished without the ability to overload the simple assignment operator ( = ). I vaguely recall reading somewhere that there is a reason for this having to do with syntax ambiguity. Can this problem be solved so that = can be overloaded? Don Wills _______________________________________________ swift-evolution mailing list [email protected] <mailto:[email protected]> https://lists.swift.org/mailman/listinfo/swift-evolution

Untracked with Trackbuster < Your contacts automatically up to date | evercontact ; _______________________________________________ swift-evolution mailing list [email protected] <mailto:[email protected]> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution

Hello Ilya,

Yes, I meant for the email to go to the list. > Nope, that doesn't work because of my comment above. That's the change to Swift I am hoping will be adopted for 3.0. Did you try this? The idea is to write a function for multiplying a Number and an Int, so the rhs will create a Number which will then be set to the variable. It should work actually.

Yes, I've written a class named Number with many "func <operator> ( ... ) { ... }" implementations for the various permutations of Number, Double and operators. They all work except for when <operator> is the equal sign.

On Dec 6, 2015, at 3:05 PM, ilya <[email protected]> wrote:
On Mon, Dec 7, 2015 at 00:47 Don Wills <[email protected] <mailto:[email protected]>> wrote: Hello Ilya, On Dec 6, 2015, at 1:09 PM, ilya <[email protected] <mailto:[email protected]>> wrote: On Sun, Dec 6, 2015 at 5:26 PM, Don Wills via swift-evolution <[email protected] <mailto:[email protected]>> wrote: Silvan, Yes, I understand the concern you raise. I too have held that general opinion of overloading operators in other languages for many years. That said, overloading arithmetic and other operators causes the same opportunity for abuse. For example, overloading + for integers to do something different (like rounding instead of truncation) would make maintenance of existing programs into a giant guessing game. That said, once the cat is out of the bag to overload operators, I don't see how adding support for = makes things any worse. This is not really the same. You only use + explicitely, but the compiler must insert some assigments automatically, for example by copying when the function closes over some variables. It must know exactly what the semantics in this case is to be able to compile correct program.
FYI, the reason for my suggestion is to add support for fixed decimal arithmetic just like that available in COBOL. Yeh I can hear the groans now. I'm with you. However, for business applications, fixed decimal arithmetic is a basic feature that has been tossed away in new languages by language designers who don't actually labor in the trenches. I didn't look into the new Foundation, but doesn't it contain NSDecimalNumber? I've built a simple class to do just that - here is some sample code that uses my Number class that gives an idea of what the code does: var amount = Number(left: 6, right: 2); var result = Number(left: 9, right: 2); amount <- 3.9; amount += 1; result <- amount * 4; print(result) I'm not sure why you feel the need to overload = in this example. If Number * Int -> Number is defined, you can just use result = amount * 4
John, The ability to overload operators is very useful. However, that utility is diminished without the ability to overload the simple assignment operator ( = ). I vaguely recall reading somewhere that there is a reason for this having to do with syntax ambiguity. Can this problem be solved so that = can be overloaded?

I guess I missed the subtlety that in Swift the statement "x = y;" is fundamentally different than "x += y;". That surprises me.

It shouldn’t. I am not aware of any languages in which = (or its equivalent) is just a normal overloaded operator. Even in C++, (1) there are different formation rules for assignment operators, (2) assignment operators are often implicitly generated, (3) explicitly declared assignment operators can have subtle effects on formal language behavior, and (4) the resolution rules for assignment are different from the rules for other user-defined operators, even compound assignment.

Oh, and of course (5) the token “=" doesn’t mean assignment in the contexts where it actually means initialization, which is something that was actually confused earlier in this thread, and which is probably the single most common point of confusion among even quite knowledgeable C++ programmers — and which is, by and large, a problem that we’ve defined away in Swift by not introducing this kind of semantic confusion around the behavior of =.

And it fails one of the basic principles that I've always applied to software design: The Principle of Least Astonishment.

In fact, in my experience, programmers tend to be quite astonished by the behavior of overloaded assignment.

Again, the feature you actually need for all of your examples is literal convertibility, which already exists; please look into it before writing off the language.

On Dec 6, 2015, at 10:17 PM, Don Wills <[email protected]> wrote: On Dec 6, 2015, at 10:54 PM, John McCall <[email protected]> wrote: On Dec 6, 2015, at 5:44 AM, Don Wills via swift-evolution <[email protected]> wrote:
Thanks for your response, even though it is quite disheartening to me. As I get to know the nuances of Swift, I'm starting to think that moving to Swift might be too big of a stretch for my programming staff. Don Wills

Thanks to all who replied. I apologize that my responses were disjoint - my spam checker delayed a couple of the messages until this morning.

To those who suggested literal convertibles, I believe Stephen is correct in that it is insufficient to accomplish the semantics that I want with the syntax I had hoped for. It is about more than just initialization. I'll probably just use ":=" as the assignment operator. Not optimal, but it works.

On Dec 6, 2015, at 11:59 AM, Stephen Celis <[email protected]> wrote: I think that his number assignment (via `<~`) depends on the current state of `amount`, and that using FloatLiteralConvertible does not provide enough information at the call site (since the current value is not available in the initializer).

For what it's worth, you can accomplish a lot of assignment operator overload behavior via property get/set/willSet/didSet (similar to how Ruby methods suffixed with "=" are dispatched via dot notation), though it would require you to design your interface so that "=" is called on a property.

On Mon, Dec 7, 2015 at 9:15 AM, Don Wills via swift-evolution < [email protected]> wrote:

Thanks to all who replied. I apologize that my responses were disjoint - my spam checker delayed a couple of the messages until this morning. To those who suggested literal convertibles, I believe Stephen is correct in that it is insufficient to accomplish the semantics that I want with the syntax I had hoped for. It is about more than just initialization. I'll probably just use ":=" as the assignment operator. Not optimal, but it works. Don > On Dec 6, 2015, at 11:59 AM, Stephen Celis <[email protected]> > wrote: > > I think that his number assignment (via `<~`) depends on the current state of `amount`, and that using FloatLiteralConvertible does not provide enough information at the call site (since the current value is not available in the initializer). _______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution

Digital Bunker

Overloading & Creating New Operators In Swift 5

We'll cover everything you need to know about operator overloading and creating custom operators with unique precedence and associativity behavior.

Operator overloading allows you to change how existing operators (e.g. + , - , * , / ,  etc.) interact with custom types in your codebase. Leveraging this language feature correctly can greatly improve the readability of your code.

Let’s say we had a struct to represent Money :

Now, imagine we’re building an e-commerce application. We’d likely need a convenient way of adding up the prices of all items in our shopping cart.

With operator overloading, instead of only being able to add numeric values together, we could extend the + operator to support adding Money objects together. Moreover, as part of this implementation, we could even add logic to support adding different currency types together!

In order to take advantage of this language feature, we just need to provide a custom implementation for the operator in our type's implementation:

You may have even used operator overloading without realizing it. If you've ever implemented the Equatable protocol, it requires you to provide a custom implementation for the == operator:

I hope you'll agree that, in these examples, operator overloading has increased the code's readability and expressiveness. However, we should be careful not to overdo it.

Whenever you're creating or overriding an operator, make sure its use is obvious and undisputed. Language features like this often produce diminishing returns, as the more custom behavior we introduce, the harder it is for other developers to understand our code.

Creating Custom Operators

Whenever we're discussing custom operators, overloading an existing operator is always going to be the easier option. Assuming, of course, this doesn't compromise the code's legibility.

Instead, if we want to create our own operator, we'll need to specify 3 additional pieces of information: the type of the operator, the precedence order, and the associativity behavior.

When we're simply overloading an existing operator, we inherit all of this information from the parent operator directly.

Operator Types

When we want to create our own operator, we’ll need to specify whether it's of the prefix , postfix , or infix variety.

prefix - describes an operator that comes before the value it is meant to be used with (e.x. !isEmpty )

postfix - describes an operator that comes after the value it is meant to be used with (e.x. the force-unwrapping operator - user.firstName! )

prefix and postfix are also referred to as "unary” operators as they only affect a single value.

infix - describes an operator that comes in between the value it is meant to be used with and is the most common type (e.x. + , - , / , * are all infix operators)

infix are also referred to as "binary” operators since they operate on two values.

For the statement - 2 + 5 x 5  - we know that the answer is 2 + (5 x 5) => 27 because the precedence of the operators involved tell us the order in which to evaluate the expression.

In the same way that the higher precedence of multiplication resolves the ambiguity in the order of operations here, we need to provide the compiler with similar information when we create a custom operator.

By specifying the precedence, we can control the order in which the expression is evaluated as operations belonging to a higher precedence group are always evaluated first.

We'll see how to specify the precedence of our operator shortly, but let's understand the current state of affairs in Swift first.

The following image shows a list of all precedence group types in Swift from the highest priority to the lowest priority:

overload assignment operator swift

If you declare a new operator without specifying a precedence group, it is a member of the DefaultPrecedence precedence group which has no associativity.

Associativity

The associativity of an operator is simply a property that specifies how operators of the same precedence level are grouped in the absence of parentheses.

Imagine we have an expression with multiple operators all belonging to the same precedence level:

We could process this expression in 2 different ways:

(20 / 2) / 5

20 / (2 / 5)

which would give us 2 and 50 , respectively.

This ambiguity is exactly what the operator's associativity helps us resolve.

An operator can be associative (meaning the operations can be grouped arbitrarily), left-associative (meaning the operations are grouped from the left), and right-associative (meaning the operations are grouped from the right).

In the simplest terms, when we say an operator is left-associative we simply evaluate our expression from left to right. Conversely, for a right-associative operator, we evaluate our expression from right to left.

As another example, we know that * , / , and % all have the same precedence, but by changing their associativity, we can get wildly different results:

Left-Associative

(4 * 8) / 2 % 5 ==> (32 / 2) % 5 ==> 16 % 5 ==> 1

Right-Associative

4 * 8 /(2 % 5) ==>  4 * ( 8 / 2) ==> 4 * 4 ==> 16

Put differently, operator associativity allows us to specify how an expression should be evaluated when it involves multiple operators of the same precedence group.

All arithmetic operators are left-associative.

In order for expressions involving our custom operator to evaluate correctly, we'll need to be mindful of both the operator's precedence and associativity behavior.

Creating A Custom Operator

With all of the theory out of the way, let's create a custom operator that will allow us to easily perform exponentiation.

Since exponentiation has a higher precedence than multiplication and is right-associative, we'll need to create a new precedence group as this operation doesn't match any of Swift's existing precedence group options.

We'll create the precedencegroup by filling in the relevant fields from this template:

Next, we need to let the compiler know about the existence of our custom operator and specify its behavior:

And now, anywhere else in our code we're free to use our custom operator:

2 ^^ 8 => 256.0

It's important to mention here that our precedence group declaration and all operator declarations and functions must be placed at the file scope - outside of any enclosing type. Don't worry if you forget this, the compiler will dutifully remind you.

Limitations Of Operator Overloading

There are a few additional caveats to mention.

While ternary operator types (e.g. var userStatus = user.age >  18 ? .approved : .rejected ) also exist in Swift, the language does not currently allow for overloading their operation.

This same restriction applies to the default assignment operator ( = ) and the compound assignment operator ( += ).

Otherwise, all operators that begin with / , = , - , + , ! , * , % , < , > , & , | , ^ , ? , or ~ , or are one of the Unicode characters specified here are fair game.

Best Practices

While this language feature is extremely powerful and go a long way towards improving your code's legibility and friendliness, it can also take you in the opposite direction.

Let's take a moment to discuss some best practices around using this language feature.

Firstly, overloading operators in Swift should be done in a way that is consistent with how the operator is normally used. A new developer should be able to reason about the expected behavior of the operator without needing to check the implementation.

Next, in situations where the traditional operators don't make semantic sense, you may want to consider creating a custom operator instead.

Finally, and a more pragmatic point, they should be easy to remember and type on the keyboard - an obscure custom operator like .|. benefits no one as its meaning is neither intuitive nor is it convenient to type.

Ultimately, this is just a long-winded way of saying that custom operators, typealias , and all other forms of "syntactic sugar" can improve your code's clarity and your development speed when used with a bit of restraint and pragmatism.

If you're interested in more articles about iOS Development & Swift, check out my YouTube channel or follow me on Twitter .

Join the mailing list below to be notified when I release new articles!

Do you have an iOS Interview coming up?

Check out my book Ace The iOS Interview !

Further Reading

Want to take a deeper dive into operator overloading?

Check out these great resources:

  • https://www.codingexplorer.com/custom-operators-swift/
  • https://sarunw.com/posts/how-to-create-custom-operators-and-operators-overloading-in-swift/
  • https://jayeshkawli.ghost.io/custom-operators-in-swift/

Subscribe to Digital Bunker

This page requires JavaScript.

Please turn on JavaScript in your browser and refresh the page to view its content.

Overloading Custom Operators in Swift

In this Swift tutorial, you’ll learn how to create custom operators, overload existing operators and set operator precedence. By Owen L Brown.

Sign up/Sign in

With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!

Already a member of Kodeco? Sign in

Getting Started

Overloading the addition operator, other types of operators.

  • Mixed Parameters? No Problem!
  • Protocol Operators
  • Creating Custom Operators
  • Precedence Groups
  • Dot Product Precedence
  • Where to Go From Here?

Operators are the core building blocks of any programming language. Can you imagine programming without using + or = ?

Operators are so fundamental that most languages bake them in as part of their compiler (or interpreter). The Swift compiler, on the other hand, doesn’t hard code most operators, but instead provides libraries a way to create their own. It leaves the work up to the Swift Standard Library to provide all of the common ones you’d expect. This difference is subtle but opens the door for tremendous customization potential.

Swift operators are particularly powerful because you can alter them to suit your needs in two ways: assigning new functionality to existing operators (known as operator overloading ), and creating new custom operators.

Throughout this tutorial, you’ll use a simple Vector struct and build your own set of operators to help compose different vectors together.

Open Xcode and create a new playground by going to File ▶ New ▶ Playground . Pick the Blank template and name your playground CustomOperators . Delete all the default code so you can start with a blank slate.

Add the following code to your playground:

Here you define a new Vector type with three properties conforming to two protocols. The CustomStringConvertible protocol and the description computed property let you print a friendly String representation of the Vector .

At the bottom of your playground, add the following lines:

You just created two Vector s with simple Array s, and with no initializers! How did that happen?

The ExpressibleByArrayLiteral protocol provides a frictionless interface to initialize a Vector . The protocol requires a non-failable initializer with a variadic parameter: init(arrayLiteral: Int
) .

The variadic parameter arrayLiteral lets you pass in an unlimited number of values separated by commas. For example, you can create a Vector such as Vector(arrayLiteral: 0) or Vector(arrayLiteral: 5, 4, 3) .

The protocol takes convenience a step further and allows you to initialize with an array directly, as long as you define the type explicitly, which is what you’ve done for vectorA and vectorB .

The only caveat to this approach is that you have to accept arrays of any length. If you put this code into an app, keep in mind that it will crash if you pass in an array with a length other than exactly three. The assert at the top of the initializer will alert you in the console during development and internal testing if you ever try to initialize a Vector with less than or more than three values.

Vectors alone are nice, but it would be even better if you could do things with them. Just as you did in grade school, you’ll start your learning journey with addition .

A simple example of operator overloading is the addition operator. If you use it with two numbers, the following happens:

But if you use the same addition operator with strings, it has an entirely different behavior:

When + is used with two integers, it adds them arithmetically. But when it’s used with two strings, it concatenates them.

In order to overload an operator, you have to implement a function whose name is the operator symbol.

Add the following piece of code at the end of your playground:

This function takes two vectors as arguments and return their sum as a new vector. To add vectors, you simply need to add their individual components.

To test this function, add the following to the bottom of your playground:

You can see the resultant vector in the right-hand sidebar in the playground.

The addition operator is what is known as an infix operator, meaning that it is used between two different values. There are other types of operators as well:

  • infix : Used between two values, like the addition operator (e.g., 1 + 1 )
  • prefix : Added before a value, like the negation operator (e.g., -3 ).
  • postfix : Added after a value, like the force-unwrap operator (e.g., mayBeNil! )
  • ternary : Two symbols inserted between three values. In Swift, user defined ternary operators are not supported and there is only one built-in ternary operator which you can read about in Apple’s documentation .

The next operator you’ll want to overload is the negation sign, which will change the sign of each component of the Vector . For example, if you apply it to vectorA , which is (1, 3, 2) , it returns (-1, -3, -2) .

Add this code below the previous static function, inside the extension:

Operators are assumed to be infix , so if you want your operator to be a different type, you’ll need to specify the operator type in the function declaration. The negation operator is not infix , so you add the prefix modifier to the function declaration.

At the bottom of your playground, add the line:

Check for the correct result in the sidebar.

Next is subtraction, which I will leave to you to implement yourself. When you finish, check to make sure your code is similar to mine. Hint: subtraction is the same thing as adding a negative.

Give it a shot, and if you need help, check the solution below!

[spoiler title=”Solution”]

Test your new operator out by adding this code to the bottom of your playground:

All videos. All books. One low price.

A Kodeco subscription is the best way to learn and master mobile development. Learn iOS, Swift, Android, Kotlin, Flutter and Dart development and unlock our massive catalog of 50+ books and 4,000+ videos.

AppCoda

  • Beginning iOS Programming with Swift
  • Intermediate iOS Programming with Swift
  • Mastering SwiftUI
  • Mastering Machine Learning with Core ML and Python
  • Swift Course
  • All Tutorials
  • App Marketing
  • App Showcase
  • App Template
  • Write for Us

An Introduction to Operator Overloading in Swift

Cosmin pupăză.

  • 29th Mar '16

Operator overloading is one of the most powerful features of any computer programming language, so Apple decided to make it available for development in Swift. However, with great power comes great responsibility. You can easily implement really weird scenarios with it, such as making the subtraction operator add numbers or the division one multiply them, but that is definitely not what you want to do with it.

OK, enough talking – let’s see what operator overloading is all about.

The Challenge

Your task for this tutorial is an easy one: extend the multiplication operator’s standard functionality for numbers so that it works for strings as well. You are going to use the string concatenation operator under the hood, since you can imagine the whole thing like this:

Before diving into coding, think how you would solve the problem and break it into steps. This is how I would do it:

  • Create the result variable and assign its initial value – the default string.
  • Loop through the numbers from 2 to the number of concatenations and do only one thing for each iteration – add the string to the result.
  • Print the result to the console.

That’s it for the algorithm – let’s move on to the implementation.

Basic Operator Overloading

Fire up Xcode and open a playground. Delete everything from it and add the multiplication operator function’s prototype:

The function has two parameters – the left hand side operand of type String and the right hand side operand of type Int – and returns the multiplication result as String .

There are three things you should do inside the function’s body. First of all, create the result variable and assign its initial value – the function’s String argument – it is variable because you are going to change its value soon:

Next loop through the numbers from 2 to the function’s Int argument with the for in control flow statement and the closed range operator:

Note: You implement the wildcard pattern matching with the underscore since you ignore the sequence values – read more about loops here .

There is only one thing you should do in the loop – update the result with the string value:

Note: You could also do it like this – the initial approach is shorter because it uses the addition assignment operator:

Finally, return the result:

Now let’s use the operator:

That’s it! There is only one problem – you can only use the operator to multiply strings. How about other value types? Let’s fix this with generic operators.

Generic Operators

Generic types don’t work with operators by default, so you need a protocol for that. Add its prototype to the playground:

Now add the addition assignment operator function’s prototype to the protocol:

The function has both the left hand side and right hand side operands of type Self – this is just a fancy way of saying that they are of any type which implements the protocol. The left hand side operand is marked as inout , since its value is modified and returned from the function.

Alternatively, you can define the addition operator function’s prototype:

The function has both the left hand side and right hand side operands of type Self and returns the addition result as a value of type Self . In this case, you do not need to use inout parameters anymore.

Next, create extensions for the String , Int , Double and Float types that implement the Type protocol:

Note: The implementation of the extensions are empty because you don’t want to add anything to the default types. You simply make them in order to conform to the protocol.

Now add the multiplication operator function’s prototype to the playground file:

The function takes in two parameters – the left hand side operand of type T and the right hand side operand of type Int – and returns the multiplication result as a value of type T . You use a type constraint to make the generic type T conform to the Type protocol, so it now understands the addition assignment operator.

Note: You can define the type constraint with the where keyword instead – the initial approach is shorter though:

The function’s implementation is exactly the same as in the previous case:

Note: You can use the addition operator instead – make sure to add its function prototype to the protocol in this case.

Now let’s see the generic operator in action:

That’s it! There is only one problem: you are using the standard multiplication operator. That’s a bit confusing. It would better if we can change it to other operators. Okay, let’s see how we can fix this with custom operators.

Custom operators

Add this line to the playground file to get started:

Here’s what’s going on here, step-by-step:

  • The custom multiplication operator’s name is ** .
  • Its type is infix since it is a binary operator with two operands.
  • It evaluates from left to right, so it has a left associativity.
  • Its precedence is 150 – the same as the standard multiplication operator’s one, since it is a high priority operator.

Note: You can read more about operator precedence and associativity here .

The custom operator function’s prototype is similar to the standard one – just its name is different:

The function’s implementation is exactly the same as before:

Here’s the custom operator in action:

That’s it! There is only one problem – the operator’s compound version is not defined yet, so let’s fix this in the next section.

Compound Operators

The compound operator’s type, precedence and associativity is exactly the same as in the previous case – only its name is different:

Next add the compound operator function’s prototype to the playground:

The function doesn’t have a return type, since its left hand side operand is marked as inout .

There is only one thing you should do in the function’s body – use the custom operator defined earlier to return the multiplication result:

That’s it – it can’t get any simpler than that!

Operator overloading, used with caution, can be extremely powerful – I hope you find a way to use it in your own projects.

For reference, you can download the Playground file on GitHub . I have tested the code on Xcode 7.3 and Swift 2.2.

What do you think about this tutorial and operator overloading? Please leave me comment and share your thought.

Cosmin Pupăză

Cosmin Pupăză blogs about Swift and iOS development at cosminpupaza.wordpress.com and on the Swift tutorial teams at raywenderlich.com and appcoda.com. When not coding, he plays the guitar or studies WW2 history. You can contact him at [email protected] , on Facebook, Twitter and Google+.

Related Articles

How to draw lines and create pie charts using swiftui, building an interactive voice app using custom siri shortcuts in ios 12, using asyncimage in swiftui for loading images asynchronously.

Hao Zhai

Great tutorial! As you pointed out, operator overloading is a powerful tool that could be abused to create code that’s clever but hard to follow. Lately I’ve been bitten by the functional bug, which makes me allergic to for loops. Here is an alternative implementation that’s a little less imperative:

protocol Type { func +(lhs: Self, rhs: Self) -> Self }

extension String: Type {} extension Int: Type {} extension Double: Type {} extension Float: Type {}

infix operator ** {associativity left precedence 150}

func **(lhs: T, rhs: Int) -> T { let items = Array(count: rhs-1, repeatedValue: lhs) return items.reduce(lhs){$0 + $1} }

Cosmin

Good point – I like your implementation! I am a big functional programming fan as well – you can check out my imperative vs functional programming techniques tutorial series on my blog: https://cosminpupaza.wordpress.com/tutorials/ . The imperative approach adds boilerplate code, but it’s more suitable for beginners than its functional counterpart, which is more abstract and hard to understand, so that’s why I’ve chosen this approach for the tutorial. Cheers! 🙂

Cancel Reply

Save my name, email, and website in this browser for the next time I comment.

facebook_pixel

Coding Explorer Blog

Exploring how to code for iOS in Swift and Objective-C

Operator Overloading — Tailor Swift To Your Needs

Last updated on August 12, 2020

Sorry, but I have been waiting for months to make this pun.  So today, we are going to talk about Operator overloading in Swift.  This tool is very useful, but quite dangerous as well.  The “With great power comes great responsibility,” quote is very appropriate for operator overloading.  It can make your code a lot more concise, making even a function call seem like a 3-hour long lecture.  But with that, you can also make the code nigh-unreadable to anybody that is new to your code.

Be very careful with this tool, and use it where it make sense, such as how “adding” two Swift Strings together makes a new string with one string first, then the other afterwards.  You can make the addition operator print to the screen, make a network request, play music, or whatever else you could write a function for, but doing any of those would be a terrible idea in production code.  You should do only what is necessary for the operator and nothing else.  If you need different things like those, make an appropriately named function that makes it obvious that it will make a network request.

Whenever you think of whether to use operator overloading, you have to ponder whether it helps your code anymore than a simple function call.  The function call may be longer, but it is a whole lot more expressive as to what it does (if named appropriately).  If it looks like you are adding, subtracting, checking equality, or whatever else the built-in operators do though, and you do it enough in your code, Swift’s operator overloading may be the right tool for the job.

Operator Overloading

You should only use operator overloading in a way that is consistent with how the operator is normally used in Swift.  Here is an example I thought of that could make sense, though there are still some pitfalls with it.  Let’s say we want to find the amount of time between two Date objects.  It would make sense to get that via “laterDate – initialDate” right?  So let’s do that:

In this case, I chose the Calendar.Components of year, month, day, hour, minute, and second as the components to use in this subtraction.  Herein lies ones of the pitfalls.  There are several other Components I could choose.  If I just wanted to know the weeks between something, I could put that in instead for this.  Nonetheless, using these units give us what we would want in most calendrical calculations.  The next line just creates the DateComponents object using components:from:to: from the currentCalendar.  We’re taking advantage of the fact that a single line of code that returns something can be used without explicitly writing return, because it is pretty clear to the compiler that a function that returns a date components being the only thing called in a function that also returns DateComponents would simply want to forward that return.

An operator used between two values is called an  infix operator.  There are two other overloadable types of operators known as  prefix and  postfix , like the old ++i and i++ operators of yore.

As you can see from the top, this is just a function in Swift, but instead of a text name, we have a symbol as the name.  We specify the types of inputs for the left and right parts of the expression, and then specify the return type, which for this calculation should be an DateComponents object.  Now we can use it like this:

There was a bit of setup there, but most of it should be pretty easy to understand.  We first create an initial date, which has the value of the moment the Date object was created.  Then there’s an DateComponents object that has its year, month, and minute values set.  Then the laterDate constant is made, using Calendar’s dateByAddingComponents method, so that makes a value 1 year, 5 months, and 42 minutes in the future.  Then we actually test our new capability for the ” – ” operator.  When we look at the components of the result of our subtraction, you can see it has the correct value for the year, month, and minute value for exactly how far in the future it was.

I think that this function is a marginally okay use of operator overloading.  It is using the subtraction operator how it is normally used in math.  However, it hides several assumptions.  I already mentioned that it uses certain Calendar.Components, but not all of them.  Secondly, it uses Calendar’s current variable.  I think this makes sense, but it is nonetheless hidden.

If we just use the normal function call that is behind our overloaded operator, you can clearly see what calendar it is using and which flags you want.  That is why I only say that this is a marginally okay use of operator overloading.  It makes sense, but it hides those assumptions from the reader, making them have to look up the operator overloading function to see what assumptions are made.

The Equatable Protocol

There are a few places in Swift where operator overloading is actually encouraged.  If you want to be able to compare your custom class with the ” == ” operator, you will have to overload it.  If you are going to implement this, your class should probably adopt the Equatable protocol.  The Equatable protocol is used often with Generic functions (you can read more about them here:   Generic Functions in Swift ), when it will need to check for equality inside.  If you do, you only need to implement the ” == ” operator, you get the != for free (since it is basically just negating the ” == ” operator’s answer.

The way you overload the ” == ” operator is the same as with any other infix operator, like what we did above with the ” – ” operator.  Let’s make a custom type and overload the ” == ” operator below:

Now we can compare Temperature instances with the ” == ” operator.  When an operator is overloaded, it must be marked as static.  Actually, if I had made this a struct or enum, I wouldn’t even need the initializer or the operator overloading!  If the parts in it are hashable or equatable, structs and enums can generate those methods themselves, without me needing to explicitly write them.  The same is not extended to classes, and really, this type should’ve been a struct, but I wanted to show the behavior for a type that didn’t automatically get those methods when they adopt the protocol.

Another place where operator overloading in Swift is encouraged is with the Comparable protocol.  To conform to the Comparable protocol you must implement an operator function for the ” < ” operator, as well as conform to the Equatable protocol.  With you implementing == and > operators, the compiler can figure out the !=, <, <=, and >= operators for you.  You can see an example of this in my previous post Generic Functions in Swift .  It also has another example of overloading the ” == ” operator.

I debated showing the Date subtraction example above, due to how it hides many assumptions about the code being called.  I decided to share it though, because it also highlights what you have to think about when deciding to use operator overloading in Swift.  If you are doing subtraction of dates a lot in your code, always with the same unitFlags, overloading the subtraction operator could make your code a lot more readable.

There are a few operators that you cannot overload, most notably the assignment operator ” = ” (just one equal sign).  Even if you could, I’m not sure I would want to know the chaos that would be wrought by doing so, considering how much the assignment operator is used.  You can read more about the operators you can’t overload at  Tammo Freese ‘s article Facets of Swift, Part 5: Custom Operators .

Much like Custom Subscripts in Swift , this tool is very useful, but very dangerous.   Use it wisely .

In updating this post, there are two very welcome updates to Swift that made the code for the “-” operator’s overload much nicer.  Firstly, that you can use the most common Calendar.Components with their common names (.Year, .Month, etc.) instead of the longer original ones ( . YearCalendarUnit,  .Month CalendarUnit, etc.).  Secondly, the code used to use the OR operator ” | ” to combine the unit flags.  Now, Swift lets you give it a Swift Set type for options of that sort, which itself can be created with a Swift Array literal.

I hope you found this article helpful.  If you did, please don’t hesitate to share this post on Twitter or your social media of choice.  The blog is still pretty new, and every share helps.  Of course, if you have any questions, don’t hesitate to contact me on Twitter  @CodingExplorer , and I’ll see what I can do.  Thanks!

  • The Swift Programming Language – Apple Inc.
  • Facets of Swift, Part 5: Custom Operators — Swift Programming — Medium
  • Terms Of Use
  • Privacy Policy
  • Affiliate Disclaimer

Subscribe to the Coding Explorer Newsletter

Home

Make Your Swift Code Expressive: Addition Operator Use Cases

I like reading short and expressive code. Because developer spends more time reading code than writing, expressiveness often is obligatory.

Unless shortness does not obscure the intent, I favor concise expressions over longer ones. For example:

The sample shows 2 options to concatenate strings: using addition operator + or appending(_) string method. What option do you like more? I guess the concise one greeting + who .

The operator overloading in Swift enables to write short expressions. Many types like Int , String , Array overload addition ( + ) and addition assignment ( += ) operators. It makes the manipulation of the corresponding types more intuitive.

Would you like to write expressive code? I'm sure you do! So let's continue with an interesting list of types that support operator overloading for + and += . The alternative methods with the same behavior are also presented, for comparison purposes.

1. Sum numbers

Obviously the regular usage of addition operator is meant to perform arithmetic addition on numbers. For instance, 4 + 8 is evaluated to 12 .

Because Swift is type-safe, you can apply + and += operators when both operands are exactly the same type ( Int + Int , but not UInt + Int or Float + Int ).

All Swift number types Int , Float , Double and others support addition operators. Let's see a sample:

x + y performs an arithmetic addition of two integers. Plain and simple. The expression x += y mutates x variable by appending y to it (same as x = x + y ). During this operation x is mutated, so it must declared as a variable with var .

The equivalent methods of addition operators are adding(_:) and the mutating add(_:) . These methods are available for Float and Double , but not for Int . Let's see them in action:

p and r are Double type. The invocation of p.adding(r) is the same as p + r . Respectively p.add(r) mutates p and is equivalent to p += r .

2. Concatenate strings

The addition and addition assignment operators can perform strings concatenation. For instance, "abc" + "def" creates a string "abcdef" .

Let's see an example:

message + name concatenates two strings. The statement message += name also performs a concatenation. It modifies message in place by appending to its end name string.

You can also use equivalent methods appending(_:) and mutating append(_:) , which are more verbose. Let's transform the above example:

The invocation message.appending(name) concatenates message and name , returning the result. message variable is not modified. The invocation message.append(name) is mutating the message variable and appends to its end name string.

3. Concatenate arrays

Addition operators are useful to concatenate arrays. [val1, val2] + [val3] creates [val1, val2, val3] .

The concatenated arrays must have elements of the same type.

The expression colors + darkColors creates a new array that contains elements from colors followed by elements from darkColors . colors += darkColors mutates the colors array in place, by adding to its tail elements from darkColors .

Alternatively you can use the mutating append(contentsOf:_) , which is an equivalent of addition assignment operator ( += ). Transforming the above example:

The invocation of colors.append(contentsOf: darkColors) modifies colors in place and appends the elements of darkColors .

4. Add time interval to a date

The addition operator enables expressively to add intervals to a Date . The expression date + timeInterval creates a new Date with a specified amount of time added to it. The addition assignment modifies the date in place date += timeInterval .

Let's see how it can be done:

oneDay is an interval that contains the number of seconds in 24 hours. dateFormatter creates a date for 2017-02-15 . The expression date + oneDay evaluates to a new date dayAfterDate that is created from date with oneDay time interval added to it.

If you want to modify date directly, make it a variable and use addition assignment operator += :

date =+ oneDay mutates date by adding oneDay seconds to it.

The Date methods that provide the same behavior are addingTimeInterval(_:) and the mutating addTimeInterval(_:) .

Tip about calendar

The provided way to modify a date adjusts absolute values. You may have unexpected results when adding longer time intervals like weeks or months.

Most of the times Calendar usage is preferable. It provides accurate date modifications according to daylight saving time, months with different numbers of days, and so on.

Let's update the above example and use a calendar instance Calendar.current :

5. Sum measurements

A recent Foundation update introduced measurements and units . It allows to represent distances (for instance 10 miles , 12 kilometers ), weights ( 8 kg ) and more.

The good part is that Measurement structure overloads + operator (and additionally * - / < == ). This makes measurement manipulations easy and concise.

Let's sum two distances in kilometers:

morningRun and eveningRun describe the distance someone ran in the morning and evening. Plain and simple the addition operator is used to find the daily run distance: morningRun + eveningRun .

The addition operation must sum measurements that describe the same type of physical units (length, mass, speed and more ).

For instance, it doesn't make sense to sum speed and mass values. In such case Swift triggers an error:

turtleSpeed and turtleWeight are measurements that holds different type of units: UnitLength.kilometers and UnitMass.grams . These are not compatible, and as result Swift triggers an error.

Measurement structure does not provide methods for manipulation. In this case you have to use operators only. In my opinion it's a nice decision, because operators fits good with measurements.

6. Conclusion

As seen, the addition and addition assignment operators provide short and concise syntax.

Generally these are used to sum numbers and concatenate strings.

You can also benefit from a concise syntax when concatenating arrays, manipulating dates and sum measurements.

Do you know other Swift types that implement addition operator overloading? Feel free to write a comment below!

Like the post? Please share!

Dmitri Pavlutin

About Dmitri Pavlutin

Popular posts.

COMMENTS

  1. how to overload an assignment operator in swift

    It is not possible to overload the default assignment operator (=). Only the compound assignment operators can be overloaded. Similarly, the ternary conditional operator (a ? b : c) cannot be overloaded. If that doesn't convince you, just change the operator to +=: func +=(left: inout CGFloat, right: Float) {. left += CGFloat(right) }

  2. Advanced Operators

    Swift's operator precedences and associativity rules are simpler and more predictable than those found in C and Objective-C. However, this means that they aren't exactly the same as in C-based languages. ... It isn't possible to overload the default assignment operator (=). Only the compound assignment operators can be overloaded ...

  3. How do you overload an operator in swift?

    Basically, I'm looking to overload the "+" operator so that it knows which "version" of the "+" to use depending of the type. swift; operator-overloading; operators; Share. ... how to overload an assignment operator in swift. 1. Declare overloaded += operator as mutating? 2. Swift ambiguous overloaded + operator.

  4. How to create custom operators and do operators overloading in Swift

    Not every type of operator can be overload. There are four restrictions that I know of: You can't overload and create a custom ternary operator. You can't overload the default assignment operator (=). You can overload other binary operators, including compound assignment operators such as a += 2. Only a subset of the ASCII characters are supported.

  5. Overloading assignment operator

    Overloading assignment operator. Evolution Discussion. Don_Wills (Don Wills) December 6, 2015, 1:44pm 1. The ability to overload operators is very useful. However, that utility is diminished without the ability to overload the simple assignment operator ( = ). I vaguely recall reading somewhere that there is a reason for this having to do with ...

  6. Overloading & Creating New Operators In Swift 5

    This same restriction applies to the default assignment operator (=) and the compound assignment operator ( +=). Otherwise, all operators that begin with /, ... Firstly, overloading operators in Swift should be done in a way that is consistent with how the operator is normally used. A new developer should be able to reason about the expected ...

  7. Basic Operators

    Basic Operators. Perform operations like assignment, arithmetic, and comparison. An operator is a special symbol or phrase that you use to check, change, or combine values. For example, the addition operator ( +) adds two numbers, as in let i = 1 + 2, and the logical AND operator ( &&) combines two Boolean values, as in if enteredDoorCode ...

  8. Operator Overloading in Swift Tutorial

    Enter the following in your playground to confirm Swift operators follow these same rules: var sumWithMultiplication = 1 + 3 - 3 * 2. You'll see the following result: -2. In cases where arithmetic operators have the same precedence, Swift evaluates the operators from left to right.

  9. Why does Swift need operator overloading?

    Updated for Xcode 15. Operator overloading allows the same operator - +, *, /, and so on - to do different things depending on what data you use it with. This allows us to use these symbols in various places where they would make sense: we can add two integers using +, we can append one string to another using +, we can join two arrays ...

  10. Operator overloading

    Operator overloading. Swift supports operator overloading, which is a fancy way of saying that what an operator does depends on the values you use it with. For example, + sums integers like this: let meaningOfLife = 42 let doubleMeaning = 42 + 42. But + also joins strings, like this:

  11. Overloading Custom Operators in Swift

    A simple example of operator overloading is the addition operator. If you use it with two numbers, the following happens: 1 + 1 // 2. But if you use the same addition operator with strings, it has an entirely different behavior: "1" + "1" // "11". When + is used with two integers, it adds them arithmetically.

  12. How to use operator overloading

    Operator overloading is the practice of adding new operators and modifying existing ones to do different things. Operators are those little symbols like +, *, and /, and Swift uses them in a variety of ways depending on context - a string plus another string equals a combined string, for example, whereas an integer plus another integer equals a summed integer.

  13. Operator Overloading in Swift with Examples

    The function takes in two parameters - the left hand side operand of type T and the right hand side operand of type Int - and returns the multiplication result as a value of type T.You use a type constraint to make the generic type T conform to the Type protocol, so it now understands the addition assignment operator.. Note: You can define the type constraint with the where keyword instead ...

  14. Operator Overloading

    Another place where operator overloading in Swift is encouraged is with the Comparable protocol. To conform to the Comparable protocol you must implement an operator function for the " < " operator, as well as conform to the Equatable protocol. ... There are a few operators that you cannot overload, most notably the assignment operator ...

  15. Make Your Swift Code Expressive: Addition Operator Use Cases

    The operator overloading in Swift enables to write short expressions. Many types like Int , String , Array overload addition ( + ) and addition assignment ( += ) operators. It makes the manipulation of the corresponding types more intuitive.

  16. Swift

    Advanced operators in Swift provide the programmer with increased functionality and complex value manipulation. They build upon the basic operators and include compound assignments, bitwise, and custom operators.. Compound Assignment Operator. Compound assignment operators combine the assignment operator = with another separate operation. The following operations are allowed:

  17. Compound assignment operators

    Swift has shorthand operators that combine one operator with an assignment, so you can change a variable in place. These look like the existing operators you know - +, -, *, and /, but they have an = on the end because they assign the result back to whatever variable you were using. For example, if someone scored 95 in an exam but needs to be ...

  18. How can I get access or overridden the = operator in Swift?

    4. You can not override the assignment operator (=), from the Swift Programming Language book. NOTE It isn't possible to overload the default assignment operator (=). Only the compound assignment operators can be overloaded. Similarly, the ternary conditional operator (a ? b : c) can't be overloaded.

  19. Understanding Operator Overloading in Swift

    Before we start, we will try to understand Operator Overloading by overloading the == operator. We all know the above code that the result will be, correct? 1 is always equal to 1 thus printing ...

  20. Can't overload "." operator in swift

    1. I think you might misunderstand the documentation. It is not possible to overload the default assignment operator (=). Only the compound assignment operators can be overloaded. Similarly, the ternary conditional operator (a ? b : c) cannot be overloaded. . is obviously not a compound assignment operator, it's a member selection operator.