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

  • What does the ?? operator mean in Swift 30 Sep 2021
  • Swift Ternary operator (?:) 09 Feb 2023
  • #file behavior change in Swift 5.8 15 May 2023
  • How to Save and Read Array in UserDefaults in Swift 05 Jan 2023
  • Different ways to map over Dictionary in Swift 11 Sep 2023
  • How to customize automatic synthesizing Codable for enums with associated values 13 Jan 2022

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

logo

You’ve made it this far. Let’s build your first application

DhiWise is free to get started with.

Image

Design to code

  • Figma plugin
  • Documentation
  • DhiWise University
  • DhiWise vs Anima
  • DhiWise vs Appsmith
  • DhiWise vs FlutterFlow
  • DhiWise vs Monday Hero
  • DhiWise vs Retool
  • DhiWise vs Supernova
  • DhiWise vs Amplication
  • DhiWise vs Bubble
  • DhiWise vs Figma Dev Mode
  • Terms of Service
  • Privacy Policy

github

Insights into Swift Operator Overloading: Enhancing Code Expression

Authore Name

Nidhi Sorathiya

Frequently asked questions, is there operator overloading in swift, what is overloading and overriding in swift, how to overload the default assignment operator (=) in swift, what does the === operator do in swift, what is a custom operator in swift.

Swift operator overloading allows developers to redefine how operators behave with various data types, offering flexibility and expressiveness in code.

We’ll delve into the mechanics of operator overloading, covering existing operators and the creation of custom ones. This power feature enables writing clean, intuitive code that can be tailored to specific programming needs, making Swift a dynamic tool for developers. Join us to unlock the potential of operators in Swift and enhance your coding skills.

Fundamentals of Swift Operator Overloading

In Swift, operator overloading is the process where you provide a custom implementation of an existing operator, such as the addition operator (+), or present an entirely new operator, to work with the types you define. This process not only increases the readability and conciseness of your code but also enables the performance of complex operations in a simplified manner.

Operator overloading in Swift uses specific keywords and syntax to redefine the operator's functionality. When you overload an operator, you tell the compiler how to use that operator with your custom types. The overloading operators must be marked with the static keyword and can be defined within class, struct, or enum types to perform operations that involve their instances.

Swift provides a comprehensive set of operators, which are categorized as unary, binary, and ternary:

• Unary operators operate on a single target. These include unary prefix operators, such as the logical NOT operator (!), and unary postfix operators, like the increment operator (++) that Swift deprecated in favor of the += 1 operation.

• Binary operators work with two values and include common operators like the addition and subtraction operators (+ and - ).

• The ternary conditional operator is a unique operator in Swift that works with three targets. The ternary conditional operator (?:) is the only ternary operator in Swift.

Key benefits of using operator overloading include:

• Improving code readability by allowing complex operations to be expressed succinctly

• Adding custom behavior to existing operators, tailoring them to work with your custom types

• Facilitating the implementation of domain-specific languages within your applications

While redefining operators might seem straightforward, developers should employ operator overloading judiciously. Overuse or inappropriate application of operator overloading can lead to code that's hard to understand and maintain. Therefore, it is essential to adhere to logical and conventional meanings of operators while engaging in operator overloading to maintain code clarity.

Exploring Operators in Swift

Before delving into the intricacies of Swift operator overloading, it's crucial to recognize the fundamental role of operators in the Swift programming language. Operators are special symbols or phrases that you use to check, change, or combine values. Swift supports most standard arithmetic operators and improves upon them with enhanced functionality such as overflow operators and compound assignment operators.

The arithmetic operators (addition + , subtraction - , multiplication * , and division / ) are familiar to most programmers and are often the first that come to mind. Additionally, Swift includes a range of comparison operators such as == , != , > , < , >= , and <= that compare two values and return a Bool. Beyond these common operators, Swift provides operators that aren't as universally known or used, such as the nil coalescing operator ( ?? ) and range operators ( ..< and ... ).

Understanding how these operators function is the prerequisite for comprehending operator overloading. The operators in Swift are generally categorized into:

Unary operators (a): An operator that prefixes (!b) or postfixes (i++) a single operand.

Binary operators (a + b): An operator that is placed between two operands and inflicts some form of computation or logical operation.

Ternary operators (a ? b : c): An operator that works with three parts, the most famous example being the ternary conditional operator which evaluates a condition to return one of two values.

Swift emphasizes safety and performance, and the design of its operator system follows the same philosophy. A well-defined precedence and associativity for each operator ensures that complex expressions can be evaluated predictably without the need for excessive parentheses.

The Syntax for Swift Operator Overloading

Swift operator overloading requires developers to become familiar with a syntax specifically designed for this feature. Overloading an operator involves creating a function with a special name, that name being the operator we wish to overload, and implementing our custom behavior within it. These functions need to be marked as static and placed within the appropriate scope—whether that's a class, struct, or enum definition—since they pertain to the type itself rather than its instances.

Overloading Existing Operators

To overload an existing operator, you declare and implement a static method with the name of the operator as the function's name. It’s defined using the operator keyword, followed by the operator itself within a pair of parentheses. For example, overloading the addition operator for a custom Vector type would look like this:

Creating Swift Custom Operators

When defining custom operators, first declare the operator using the prefix, infix, or postfix keywords to specify the type of operator you're creating. Next, you need to define its functionality similarly to how you overload an existing operator, but with the new operator's symbol. Custom operators can include characters like / , = , - , + , ! , * , % , < , > , & , | , ^ , ? , and ~ .

Here's an example of declaring and implementing a custom infix operator ** for exponentiation:

In the example, we also define a precedence group, another important aspect of infix operators. This defines how your custom infix operator interacts with others regarding operator precedence and associativity rules.

Overall, when overloading operators, you must collaborate with Swift's type system to ensure that the compiler interprets your overloads correctly. It’s necessary to specify the types of the operands and the return type accurately to avoid any ambiguity. Whether you're overloading operators for existing types or your custom types, Swift’s structure for operator overloading demands precision and foresight, ensuring your custom operators function seamlessly in various contexts.

Dive into Custom Operators

Swift goes a step beyond enabling the overloading of existing operators by allowing developers to define custom operators. This means you can create an operator symbolically represented in a way that makes sense for your code’s context. These custom operators can then be overloaded with specific functionality related to your data types.

What Are Swift Custom Operators?

Custom operators are new symbols that you introduce as operators in your code. These can serve to make expressions more readable and concise, particularly when you’re performing operations that are unique to your program's domain. Swift custom operators can be defined with the prefix, infix, or postfix notation, depending on how they are used relative to their operands.

Declaring and Implementing Custom Operators in Swift

To declare a custom operator, you use the operator keyword followed by the operator symbol and a prefix, infix, or postfix modifier, depending on how the operator should be used. Once declared, you must also define the operator's functionality by implementing a function with the same symbol, appropriately marked with the static keyword as it relates to the type itself.

In the code snippet above, we’ve created a new prefix operator +++ that increments an integer by 2.

Practical Examples of Custom Operators Usage

Using custom operators can significantly cut down boilerplate code and provide a level of abstraction similar to that of functions or methods. Suppose you’re working on a graphics-related application where manipulating pixel data is common. A custom operator for combining color values could streamline the process:

This mixture operator <+> succinctly expresses the idea of combining two colors, something that might otherwise require a more verbose function or method call.

Custom operators are a powerful feature in Swift, allowing us to write code that's more aligned with the domain we're working in. However, they should be used judiciously to ensure that code remains approachable and intuitive for other developers.

In our next sections, we will dive deeper into the overloading of specific types of operators and discuss their importance and implications by exploring prefix, infix, and ternary conditional operator overloading in Swift.

Defining Prefix and Postfix Operators

Swift’s prefix and postfix operators function with only a single operand and are known for their clarity and efficiency when implemented correctly. The prefix operator appears before its operand, while the postfix operator follows it. Consider the unary minus (-) as a prefix or the increment (++) as a postfix in other programming languages.

Understanding Prefix Operator Overloading

Let's look at an example of how to overload a prefix operator in Swift. A common scenario might involve negating some property of a custom type:

In this instance, we define and implement the unary minus operator for a custom Currency type to convey the concept of debt.

Case Study: Implementing a Prefix Operator

To further illustrate, consider a graphics application where you might want to invert colors. A prefix operator could be an ideal way to express this action:

Here, the ~~ operator has been created to cleanly signify the inversion of a color.

Implementing Infix Operators

Infix operators are those that are written between their two operands, such as the multiplication ( * ) and division (/) operators. New infix operators must provide precedence and associativity to dictate how they interact with other infix operators.

The Role of Infix Operator Overloading in Swift

The true power of Swift comes into play when you combine custom types with infix operator overloading. This can create notations that are highly expressive and domain-specific, which improves both code readability and functionality.

For instance, let's say you have a custom-type Fraction that represents a mathematical fraction:

The custom infix operator %% can be used to add two Fraction instances together with appropriate logic inside the implementation.

Rules for Infix Operator's Precedence and Associativity

When creating new infix operators, you must specify their precedence and associativity:

Here, the *** operator is given the same precedence as standard multiplication, ensuring expressions involving both are evaluated in the expected order.

Precedence and Associativity in Infix Operators

To manage the complexity of expressions with multiple operators, Swift uses precedence and associativity rules. When creating custom infix operators, it's essential to define where they stand in the operator hierarchy to ensure the correct order of operations.

Establishing Precedence for Infix Operators

Precedence in Swift dictates the order in which operations are performed in a compound expression. Every infix operator belongs to a precedence group, which determines this order. When you create a custom infix operator, you should assign it to a precedence group to define how it interacts with other infix operators.

Here's an example of establishing a custom infix operator for vector cross-product with its precedence:

In the example above, the new operator >< for cross-product takes its place in the precedence hierarchy, ensuring it evaluates correctly in mixed expressions.

Understanding Precedence and Associativity Rules

Operator precedence dictates which operator is applied first in an expression, while associativity decides the grouping of operators with the same precedence.

For example:

In expressions with operators of the same precedence group, associativity becomes important:

Overloading the Ternary Conditional Operator

Swift only includes one ternary operator: the ternary conditional operator ? :, which is used to choose between two expressions based on a given condition. Because of its unique nature and established behavior, the ternary conditional operator is not overloadable in Swift. This restriction is intentional to preserve the readability and predictability of ternary conditionals—constructs that developers rely upon to be consistent in their function.

Can You Overload the Ternary Conditional Operator?

Currently, overloading the ternary conditional operator is not supported in Swift. Attempting to do so would complicate the language's grammar and introduce ambiguity, making code harder to understand and maintain.

Why Overloading the Ternary Conditional Operator is Rare

Unlike infix, prefix, and postfix operators, the ternary conditional operator has a fixed and well-understood behavior, tightly integrated within the language's syntax. Swift's decision to make it non-overloadable preserves the clear and concise semantics that ternary conditionals are known for.

Operator overloading enhances Swift's customizability and expressive power, but with great power comes great responsibility. It's crucial to use custom operators sparingly and thoughtfully to keep code understandable and prevent confusion. With a robust understanding of precedence, associativity, and restraint, developers can use Swift operator overloading to create powerful and expressive syntax tailored specifically to their domains.

Advanced Swift Operator Overloading Techniques

Overloading operators for custom types can give you powerful ways to express the operations that those types can undergo. As you work with complex data structures or mathematical concepts, you will discover that the ability to provide natural expressions for operations can make your code not only more elegant but also more closely aligned with the domain you're working with.

Overloading Operators for Custom Types

Swift operator overload provides an opportunity to define the behavior of standard operators for your custom types or to create entirely new operators. When adding operator overloading to custom types, consider the types of operations that are integral to the type's function.

Let's take an example where we develop a Matrix type in a linear algebra library:

By overloading the multiplication ( * ) operator, we can provide a matrix multiplication operation directly on Matrix instances, making the library more intuitive.

Ensuring Type Safety with Operator Overloading

Swift’s type system plays a crucial role in operator overloading as it helps maintain type safety. It’s important to ensure that the types your operators work with are handled correctly:

In the code above, we use Swift's guard statement to ensure that we only add matrices of the same dimensions, preserving type safety and reducing potential run-time errors.

Operator overloading in Swift also includes the ability to specify the result type of an overloaded operator, allowing for more complex transformations, as long as they adhere to the rules of the language's type system.

Best Practices for Swift Operator Overloading

Using operator overloading in Swift can make your code more intuitive and concise. However, with such power comes the responsibility to use it wisely. Adhering to best practices ensures that the code is not only performant and reliable but also maintainable and easy to understand.

When to Overload Operators: Practical Guidelines

Overload operators when it can simplify code without sacrificing clarity. Avoid overloading operators in a way that could confuse someone reading your code—operators should do what is expected of them. For example, it makes sense for the + operator to represent addition or concatenation but using it for subtraction would defy convention and lead to confusion.

Adhere to the following guidelines:

• Overload operators when you have a clear and natural meaning for them.

• Consider the mathematical properties of operators (such as commutativity and distributivity) to retain consistency of operations.

• Document your overloaded operators well, explaining how and why they're used.

Pitfalls to Avoid with Swift Operator Overloading

Avoid these common pitfalls when working with Swift operator overloading:

• Overcomplicating expressions by using too many custom operators.

• Violating the principle of least astonishment—don't give operators unexpected behaviors.

• Overloading too many operators for a single type leads to complex and unintelligible code.

Striking the right balance requires a thoughtful approach to design and a thorough understanding of how operator overloading affects code readability and maintainability.

Swift operator overloading is a powerful feature that, when used correctly, can make your code more expressive and tailor it to the problem at hand. We've explored the syntax and semantics of overloading existing operators and creating new custom operators, as well as practices to keep in mind to maintain clean and understandable code.

Incorporate these techniques rudely in your Swift projects and witness the transformation in how you conceptualize and implement logic around data types and operations. Happy coding!

Short on time? Speed things up with DhiWise!!

Tired of manually designing screens, coding on weekends, and technical debt? Let DhiWise handle it for you!

You can build an e-commerce store, healthcare app, portfolio, blogging website, social media or admin panel right away. Use our library of 40+ pre-built free templates to create your first application using DhiWise.

Sign up to DhiWise for free

IMAGES

  1. C++ Overloading the Assignment Operator [4]

    assignment operator overload swift

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

    assignment operator overload swift

  3. Function Overloading in Swift

    assignment operator overload swift

  4. Assignment Operator Overloading In C++

    assignment operator overload swift

  5. Assignment Operator Overloading In C

    assignment operator overload swift

  6. assignment operator overload class

    assignment operator overload swift

VIDEO

  1. C++ 26: Member Wise Copy, Assignment Operator Overloading

  2. Overloading operators

  3. OOP244

  4. OOP244 NAA

  5. #20. Assignment Operators in Java

  6. OOP244ZAA