Swift
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Optionals
-
Section 4: Object-Oriented and Value Types
-
Section 5: Memory Management
-
Section 6: Generics and Error Handling
-
Section 7: Concurrency
-
Section 8: Working with Collections
-
Section 9: Codable and Data Handling
-
Section 10: Protocol-Oriented Programming
-
Section 11: Testing and Tooling
-
Section 12: Practical Projects
-
Section 13: Interview Practice
-
Section 14: More Practice Exercises
-
Section 15: More Standard Library
-
Section 16: Advanced Concurrency
-
Section 17: Foundation Framework Deep Dive
-
Section 18: URLSession and Networking Deep Dive
-
Section 19: Combine Framework
-
Section 20: SwiftUI Fundamentals for Swift Developers
-
Section 21: Server-Side Swift with Vapor
-
Section 22: Swift Package Manager Deep Dive
-
Section 23: Swift Concurrency Deep Dive
-
Section 24: More Language Features
-
Section 25: Error Handling Deep Dive
-
Section 26: Testing Deep Dive
-
Section 27: Data Structures and Algorithms in Swift
-
Section 28: More Practice Exercises
-
Section 29: More Interview Practice
-
Section 30: Swift Macros (Swift 5.9+)
-
Section 31: Property Wrappers Ecosystem
-
Section 32: Swift Interop Deep Dive
-
Section 33: iOS App Architecture Patterns
-
Section 34: Performance and Debugging
-
Section 35: App Distribution and CI/CD
-
Section 36: More Practical Projects
-
Section 37: SwiftData and Persistence
-
Section 38: More Design Patterns
-
Section 39: More Review and Practice
-
Section 40: More Foundation Deep Dive
-
Section 41: Advanced Collections in Swift
-
Section 42: Advanced Generics Practice
-
Section 43: UIKit for Legacy and Hybrid Apps
-
Section 44: watchOS and visionOS Development Basics
-
Section 45: More Networking Patterns
-
Section 46: More Testing Practice
-
Section 47: Accessibility in Swift Apps
-
Section 48: Localization
-
Section 49: More Practical Projects Round 2
-
Section 50: Swift Charts Framework
-
Section 51: More Interview and Algorithm Practice
-
Section 52: Final Practice and Mastery
-
Section 53: Swift Compiler and Build System
-
Section 54: More Concurrency Practice
-
Section 55: App Store Guidelines and Review
-
Section 56: More Design and Architecture
109: Operator Overloading and Custom Operators
I've spent a fair amount of time reviewing codebases where developers tried to make their custom types "feel" like built-in types, and usually, they go one of two ways: they're either painfully verbose or they turn the code into a puzzle that requires a Rosetta Stone to decipher. When we're dealing with types that represent mathematical concepts—like vectors, coordinates, or complex numbers—this tension becomes really obvious.
The Clutter of Verbose Methods
Imagine we're building a simple 2D physics engine. We have a Vector2D struct. The most common thing you'll do with vectors is add them together. The "safe" way to do this is to write a method. It looks like this:
struct Vector2D {
let x: Double
let y: Double
func added(to other: Vector2D) -> Vector2D {
return Vector2D(x: self.x + other.x, y: self.y + other.y)
}
}
let velocity = Vector2D(x: 10, y: 5)
let wind = Vector2D(x: 2, y: -1)
let totalForce = velocity.added(to: wind)
Now, this is perfectly fine for one operation. But physics involves chains of calculations. If you're adding five different vectors together, you end up with a nested mess of .added(to: .added(to: ...)). It's visually noisy, and it obscures the actual math you're trying to implement. You're spending more mental energy parsing the method calls than thinking about the physics.
Making it Feel Like Native Math
This is where operator overloading comes in. Swift allows us to tell the compiler, "Hey, when you see the + sign and both sides are Vector2D, run this specific logic." By overloading the existing addition operator, we can transform that clunky method call into something that looks like a textbook equation.
struct Vector2D {
let x: Double
let y: Double
static func + (lhs: Vector2D, rhs: Vector2D) -> Vector2D {
return Vector2D(x: lhs.x + rhs.x, y: lhs.y + rhs.y)
}
}
let totalForce = velocity + wind + acceleration + friction
I prefer this approach because it reduces the cognitive load. Anyone who knows basic math understands what + does. You aren't inventing a new language; you're just extending the existing one to fit your domain. The trade-off here is minimal, provided the operator's meaning remains intuitive. If you overload + to perform a subtraction or a database save, you're going to make your teammates hate you.
The Temptation of Symbol Soup
Once you realize you can overload +, you might discover that Swift lets you define entirely new operators—like <=> or +++. I'll be honest: it feels like a superpower at first. You can create a domain-specific language (DSL) that is incredibly concise.
But here is the warning I give every junior dev: custom operators are a liability in a shared codebase. When a new engineer joins the project and sees let result = a <+> b, they can't just "know" what that does. They have to stop, search the entire project for the operator definition, and then resume their work. You've just introduced a friction point into the reading process.
If you absolutely must use a custom operator, it should be because there is no existing operator that fits, and the operation is used hundreds of times across the project. For most of our work, overloading existing operators (like +, -, *, or ==) is the sweet spot. It gives you the brevity of symbols without the confusion of a secret code.
📋 Practical Task
Implementing Complex Number Arithmetic
In mathematics, complex numbers consist of a real part and an imaginary part. Adding two complex numbers is simple: you add the real parts together and the imaginary parts together.
Create a struct named ComplexNumber with two properties: real and imaginary (both Double). Instead of writing an add method, overload the + operator to allow two ComplexNumber instances to be added together using the + symbol.
Test your implementation by creating two complex numbers—for example, (3 + 2i) and (1 + 7i)—and adding them together to ensure the result is (4 + 9i).
There are no comments for now.