Operators in Swift
Welcome to Swift Operators! Operators are special symbols that perform operations on values and variables. They’re the building blocks for calculations, comparisons, and logical decisions in your programs. Swift provides a rich set of operators that make your code both powerful and expressive.
What Are Operators?
Operators are symbols that tell the compiler to perform specific operations on one or more operands (values or variables). Swift supports many types of operators, from simple arithmetic to complex logical operations.
Types of Operators
Swift operators can be categorized by the number of operands they work with:
- Unary operators - Work with a single operand (e.g.,
-a,!b) - Binary operators - Work with two operands (e.g.,
a + b,a > b) - Ternary operator - Works with three operands (Swift has one:
a ? b : c)
Arithmetic Operators
Arithmetic operators perform mathematical operations on numeric values. These are the operators you’ll use most frequently for calculations.
Addition (+)
The addition operator adds two values together:
let sum = 5 + 3print(sum) // Output: 8
let price1 = 19.99let price2 = 29.99let total = price1 + price2print(total) // Output: 49.98
// String concatenation also uses +let firstName = "John"let lastName = "Doe"let fullName = firstName + " " + lastNameprint(fullName) // Output: John DoeSubtraction (-)
The subtraction operator subtracts the right operand from the left operand:
let difference = 10 - 4print(difference) // Output: 6
let temperature = 25.5let drop = 5.3let newTemperature = temperature - dropprint(newTemperature) // Output: 20.2
// Negative numberslet balance = 100let withdrawal = 150let result = balance - withdrawalprint(result) // Output: -50Multiplication (*)
The multiplication operator multiplies two values:
let product = 6 * 7print(product) // Output: 42
let price = 15.99let quantity = 3let totalCost = price * Double(quantity)print(totalCost) // Output: 47.97
// Calculate arealet length = 10.5let width = 8.0let area = length * widthprint("Area: \(area) square meters") // Output: Area: 84.0 square metersDivision (/)
The division operator divides the left operand by the right operand:
let quotient = 20 / 4print(quotient) // Output: 5
// Decimal divisionlet result = 10.0 / 3.0print(result) // Output: 3.333333333333333
// Integer division truncates the decimallet integerDivision = 10 / 3print(integerDivision) // Output: 3 (not 3.333...)
// Mix types by convertinglet mixed = Double(10) / 3.0print(mixed) // Output: 3.333333333333333⚠️ Important: Division by zero will cause a runtime error!
// let error = 10 / 0 // ❌ Runtime error!Remainder (%)
The remainder operator (also called modulo) returns the remainder of division:
let remainder = 10 % 3print(remainder) // Output: 1 (10 = 3 * 3 + 1)
let evenCheck = 8 % 2print(evenCheck) // Output: 0 (8 is divisible by 2)
let oddCheck = 7 % 2print(oddCheck) // Output: 1 (7 is odd)Practical use cases:
// Check if a number is even or oddlet number = 15if number % 2 == 0 { print("\(number) is even")} else { print("\(number) is odd") // Output: 15 is odd}
// Get last digit of a numberlet value = 12345let lastDigit = value % 10print("Last digit: \(lastDigit)") // Output: Last digit: 5
// Cycle through array indiceslet items = ["Apple", "Banana", "Orange"]for i in 0..<10 { let index = i % items.count print(items[index])}// Output: Apple, Banana, Orange, Apple, Banana, Orange, Apple, Banana, Orange, AppleUnary Minus (-)
The unary minus operator negates a numeric value:
let positive = 42let negative = -positiveprint(negative) // Output: -42
let temperature = -5let opposite = -temperatureprint(opposite) // Output: 5Unary Plus (+)
The unary plus operator simply returns the value unchanged:
let value = 6let result = +valueprint(result) // Output: 6
// It's rarely used but can improve readabilitylet positive = +10let negative = -10Compound Assignment Operators
Swift provides shortcuts that combine an arithmetic operation with assignment:
var score = 100
// Addition assignmentscore += 50 // Same as: score = score + 50print(score) // Output: 150
// Subtraction assignmentscore -= 30 // Same as: score = score - 30print(score) // Output: 120
// Multiplication assignmentscore *= 2 // Same as: score = score * 2print(score) // Output: 240
// Division assignmentscore /= 4 // Same as: score = score / 4print(score) // Output: 60
// Remainder assignmentscore %= 7 // Same as: score = score % 7print(score) // Output: 4Practical example:
var bankBalance = 1000.0print("Starting balance: $\(bankBalance)")
bankBalance += 500.0 // Depositprint("After deposit: $\(bankBalance)") // Output: After deposit: $1500.0
bankBalance -= 250.0 // Withdrawalprint("After withdrawal: $\(bankBalance)") // Output: After withdrawal: $1250.0
bankBalance *= 1.05 // 5% interestprint("After interest: $\(bankBalance)") // Output: After interest: $1312.5Comparison Operators
Comparison operators compare two values and return a Boolean result (true or false).
Equal to (==)
Checks if two values are equal:
let a = 5let b = 5let c = 10
print(a == b) // Output: trueprint(a == c) // Output: false
// Works with stringslet name1 = "Swift"let name2 = "Swift"let name3 = "Python"
print(name1 == name2) // Output: trueprint(name1 == name3) // Output: falseNot equal to (!=)
Checks if two values are not equal:
let x = 7let y = 3
print(x != y) // Output: trueprint(x != 7) // Output: false
// Practical uselet password = "secret123"let userInput = "password"
if password != userInput { print("Incorrect password!") // Output: Incorrect password!}Greater than (>)
Checks if the left value is greater than the right value:
let score = 85let passingGrade = 60
print(score > passingGrade) // Output: true
if score > 90 { print("Excellent!")} else if score > passingGrade { print("You passed!") // Output: You passed!} else { print("Try again")}Less than (<)
Checks if the left value is less than the right value:
let age = 16let minimumAge = 18
print(age < minimumAge) // Output: true
if age < minimumAge { print("Access denied") // Output: Access denied}Greater than or equal to (>=)
Checks if the left value is greater than or equal to the right value:
let score = 70let passingScore = 70
print(score >= passingScore) // Output: true
if score >= passingScore { print("Congratulations! You passed!") // Output: Congratulations! You passed!}Less than or equal to (<=)
Checks if the left value is less than or equal to the right value:
let temperature = 25let maxComfort = 25
print(temperature <= maxComfort) // Output: true
if temperature <= 0 { print("Freezing!")} else if temperature <= maxComfort { print("Comfortable temperature") // Output: Comfortable temperature}Logical Operators
Logical operators work with Boolean values and are essential for creating complex conditions.
Logical NOT (!)
The NOT operator inverts a Boolean value:
let isSunny = truelet isRaining = !isSunnyprint(isRaining) // Output: false
let isLoggedIn = falselet needsLogin = !isLoggedInprint(needsLogin) // Output: true
// Double negationlet value = trueprint(!!value) // Output: true (same as original)Practical example:
let hasPermission = false
if !hasPermission { print("Access denied!") // Output: Access denied!}
let isValid = trueif !isValid { print("Invalid input")} else { print("Input is valid") // Output: Input is valid}Logical AND (&&)
The AND operator returns true only if both operands are true:
let isAdult = truelet hasLicense = true
// Both must be truelet canDrive = isAdult && hasLicenseprint(canDrive) // Output: true
let isWeekend = falselet hasFreetime = truelet canGoOut = isWeekend && hasFreetimeprint(canGoOut) // Output: false (isWeekend is false)Truth table for AND:
print(true && true) // Output: trueprint(true && false) // Output: falseprint(false && true) // Output: falseprint(false && false) // Output: falsePractical example:
let age = 25let hasTicket = truelet hasID = true
// Multiple conditions with ANDif age >= 18 && hasTicket && hasID { print("Welcome to the concert!") // Output: Welcome to the concert!} else { print("Entry denied")}
// Short-circuit evaluationlet username = "admin"let password = "secret"
if username == "admin" && password == "secret" { print("Login successful!") // Output: Login successful!}Logical OR (||)
The OR operator returns true if at least one operand is true:
let isWeekend = truelet isHoliday = false
let isDayOff = isWeekend || isHolidayprint(isDayOff) // Output: true (at least one is true)
let hasCoupon = falselet isPremiumMember = falselet getsDiscount = hasCoupon || isPremiumMemberprint(getsDiscount) // Output: false (both are false)Truth table for OR:
print(true || true) // Output: trueprint(true || false) // Output: trueprint(false || true) // Output: trueprint(false || false) // Output: falsePractical example:
let temperature = 35let weatherAlert = "storm"
// Either condition triggers warningif temperature > 30 || weatherAlert == "storm" { print("Weather warning!") // Output: Weather warning!}
// Payment methodslet hasCreditCard = falselet hasPayPal = truelet hasCash = true
if hasCreditCard || hasPayPal || hasCash { print("Payment method available") // Output: Payment method available}Combining Logical Operators
You can combine multiple logical operators to create complex conditions:
let age = 20let hasParentalConsent = falselet isStudent = truelet hasID = true
// Complex conditionif (age >= 18 || hasParentalConsent) && hasID { print("Can enter") // Output: Can enter}
// Multiple conditionslet score = 85let attendance = 95let hasExtraCredit = true
if (score >= 80 && attendance >= 90) || hasExtraCredit { print("Grade: A") // Output: Grade: A}Order of operations:
// NOT (!) has highest precedence, then AND (&&), then OR (||)let result1 = true || false && falseprint(result1) // Output: true (evaluated as: true || (false && false))
// Use parentheses for claritylet result2 = (true || false) && falseprint(result2) // Output: falseRange Operators
Range operators create sequences of values, which are particularly useful with loops and collections.
Closed Range Operator (…)
The closed range operator includes both the start and end values:
// Creates a range from 1 to 5 (inclusive)let closedRange = 1...5
// Using in a for loopfor number in 1...5 { print(number)}// Output: 1, 2, 3, 4, 5
// With different valuesfor i in 10...15 { print("Counting: \(i)")}// Output: Counting: 10, 11, 12, 13, 14, 15Practical examples:
// Print multiplication tablelet num = 7for i in 1...10 { print("\(num) × \(i) = \(num * i)")}// Output: 7 × 1 = 7, 7 × 2 = 14, ... 7 × 10 = 70
// Temperature range checklet currentTemp = 25let comfortRange = 20...28
if comfortRange.contains(currentTemp) { print("Temperature is comfortable") // Output: Temperature is comfortable}
// Array slicinglet numbers = [10, 20, 30, 40, 50, 60]let subset = numbers[2...4]print(subset) // Output: [30, 40, 50]Half-Open Range Operator (..<)
The half-open range operator includes the start value but excludes the end value:
// Creates a range from 1 to 4 (5 is excluded)let halfOpenRange = 1..<5
for number in 1..<5 { print(number)}// Output: 1, 2, 3, 4
// Perfect for array indiceslet fruits = ["Apple", "Banana", "Orange", "Grape"]for i in 0..<fruits.count { print("Fruit \(i + 1): \(fruits[i])")}// Output:// Fruit 1: Apple// Fruit 2: Banana// Fruit 3: Orange// Fruit 4: GrapeWhy use half-open range?
let items = ["First", "Second", "Third", "Fourth", "Fifth"]
// Half-open range prevents index out of bounds// items.count is 5, so valid indices are 0..<5 (0, 1, 2, 3, 4)for index in 0..<items.count { print("\(index): \(items[index])")}
// This would crash: 0...items.count (tries to access index 5)// for index in 0...items.count { // ❌ Error!// print(items[index])// }One-Sided Ranges
Swift also supports one-sided ranges that continue to the end:
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
// From index 5 to the endlet fromFive = numbers[5...]print(fromFive) // Output: [6, 7, 8, 9, 10]
// From start up to (but not including) index 5let upToFive = numbers[..<5]print(upToFive) // Output: [1, 2, 3, 4, 5]
// From start up to (and including) index 5let throughFive = numbers[...5]print(throughFive) // Output: [1, 2, 3, 4, 5, 6]Practical example:
let grades = [65, 70, 85, 90, 95, 78, 88, 92]
// Get last 3 gradeslet recentGrades = grades[5...]print("Recent grades: \(Array(recentGrades))")// Output: Recent grades: [78, 88, 92]
// Get first halflet firstHalf = grades[..<4]print("First half: \(Array(firstHalf))")// Output: First half: [65, 70, 85, 90]Range Comparison
// Check if value is in rangelet score = 75let passingRange = 60...100
if passingRange.contains(score) { print("Score is in passing range") // Output: Score is in passing range}
// Multiple range checkslet age = 25switch age {case 0...12: print("Child")case 13...17: print("Teenager")case 18...64: print("Adult") // Output: Adultcase 65...: print("Senior")default: print("Invalid age")}Nil-Coalescing Operator (??)
The nil-coalescing operator provides a default value when unwrapping optionals. It’s a shorthand for checking if an optional contains a value.
Basic Usage
// Syntax: optionalValue ?? defaultValue
let optionalName: String? = nillet greeting = "Hello, " + (optionalName ?? "Guest")print(greeting) // Output: Hello, Guest
// With a value presentlet actualName: String? = "Alice"let greeting2 = "Hello, " + (actualName ?? "Guest")print(greeting2) // Output: Hello, AliceHow It Works
The nil-coalescing operator works like this:
// If optional has a value, use it; otherwise, use the defaultlet optional: Int? = nillet result = optional ?? 0// Equivalent to:// let result = optional != nil ? optional! : 0
print(result) // Output: 0
let optional2: Int? = 42let result2 = optional2 ?? 0print(result2) // Output: 42Practical Examples
User preferences:
// User settings with defaultslet userTheme: String? = nillet theme = userTheme ?? "light"print("Current theme: \(theme)") // Output: Current theme: light
let userName: String? = nillet displayName = userName ?? "Anonymous"print("Welcome, \(displayName)!") // Output: Welcome, Anonymous!
// With actual valueslet savedLanguage: String? = "English"let language = savedLanguage ?? "Default"print("Language: \(language)") // Output: Language: EnglishConfiguration values:
// API configurationlet customPort: Int? = nillet port = customPort ?? 8080print("Server running on port \(port)") // Output: Server running on port 8080
let apiKey: String? = nillet key = apiKey ?? "demo-api-key"print("Using API key: \(key)") // Output: Using API key: demo-api-key
// With timeoutlet customTimeout: Double? = nillet timeout = customTimeout ?? 30.0print("Timeout: \(timeout) seconds") // Output: Timeout: 30.0 secondsForm inputs:
// Processing form datalet userAge: String? = ""let age = userAge ?? "Not provided"print("Age: \(age)") // Output: Age: (empty string is not nil!)
// Convert and provide defaultlet ageString: String? = "25"let ageValue = Int(ageString ?? "0") ?? 0print("Age value: \(ageValue)") // Output: Age value: 25
let invalidAge: String? = "abc"let safeAge = Int(invalidAge ?? "0") ?? 18print("Safe age: \(safeAge)") // Output: Safe age: 18Chaining Nil-Coalescing Operators
You can chain multiple nil-coalescing operators:
let primary: String? = nillet secondary: String? = nillet tertiary: String? = "Fallback"
let result = primary ?? secondary ?? tertiary ?? "Default"print(result) // Output: Fallback
// Real-world example: configuration systemlet userSetting: Int? = nillet envSetting: Int? = nillet defaultSetting: Int? = 100
let finalSetting = userSetting ?? envSetting ?? defaultSetting ?? 0print("Setting value: \(finalSetting)") // Output: Setting value: 100Comparison with Optional Binding
// Using optional binding (if let)let optionalValue: String? = "Swift"
if let value = optionalValue { print("Value: \(value)")} else { print("Value: Guest")}// Output: Value: Swift
// Using nil-coalescing (more concise for simple cases)let value = optionalValue ?? "Guest"print("Value: \(value)")// Output: Value: SwiftWhen to use which:
// Use nil-coalescing for simple default valueslet name = userName ?? "Anonymous"
// Use optional binding when you need to do more with the valueif let userName = userName { print("Hello, \(userName)!") print("Your account is active") // More operations with userName} else { print("Please log in")}Operator Precedence and Associativity
Understanding operator precedence helps you predict how expressions are evaluated:
Precedence Levels
Operators with higher precedence are evaluated first:
let result = 2 + 3 * 4print(result) // Output: 14 (not 20, because * has higher precedence)
// Equivalent to:let result2 = 2 + (3 * 4)print(result2) // Output: 14
// Use parentheses to change orderlet result3 = (2 + 3) * 4print(result3) // Output: 20Common Precedence Order (highest to lowest)
- Unary operators (
!,-,+) - Multiplication, division, remainder (
*,/,%) - Addition, subtraction (
+,-) - Range operators (
...,..<) - Comparison operators (
<,<=,>,>=,==,!=) - Logical AND (
&&) - Logical OR (
||) - Nil-coalescing (
??) - Ternary conditional (
? :) - Assignment operators (
=,+=,-=, etc.)
Examples:
// Arithmetic precedencelet calc1 = 10 + 5 * 2print(calc1) // Output: 20 (5 * 2 first, then + 10)
let calc2 = 10 / 2 + 3print(calc2) // Output: 8 (10 / 2 first, then + 3)
// Comparison and logicallet value = 5let inRange = value > 0 && value < 10print(inRange) // Output: true
// Same as: (value > 0) && (value < 10)
// Mixed operatorslet complex = 2 + 3 * 4 > 10 && trueprint(complex) // Output: true// Evaluated as: ((2 + (3 * 4)) > 10) && true// (14 > 10) && true// true && true// trueBest Practice: Use Parentheses
Even when you know the precedence, use parentheses for clarity:
// Less clearlet result = a + b * c - d / e
// More clearlet result2 = a + (b * c) - (d / e)
// Complex conditionsif age >= 18 && hasID || isVIP { // Unclear intent print("Allowed")}
// Betterif (age >= 18 && hasID) || isVIP { // Clear: either (adult with ID) OR (VIP) print("Allowed")}Practical Examples and Use Cases
Example 1: Price Calculator with Discount
let originalPrice = 99.99let discountPercentage = 15.0let quantity = 3let taxRate = 0.08
// Calculate subtotallet subtotal = originalPrice * Double(quantity)print("Subtotal: $\(subtotal)") // Output: Subtotal: $299.97
// Apply discountlet discountAmount = subtotal * (discountPercentage / 100.0)let afterDiscount = subtotal - discountAmountprint("After \(discountPercentage)% discount: $\(afterDiscount)")// Output: After 15.0% discount: $254.9745
// Add taxlet tax = afterDiscount * taxRatelet finalPrice = afterDiscount + taxprint("Tax: $\(tax)") // Output: Tax: $20.39796print("Final price: $\(finalPrice)") // Output: Final price: $275.37246
// Format to 2 decimal placeslet roundedPrice = round(finalPrice * 100) / 100print("Total: $\(roundedPrice)") // Output: Total: $275.37Example 2: Grade Calculator
let exam1 = 85.0let exam2 = 92.0let exam3 = 78.0let attendance = 95.0
// Calculate average with weightslet examAverage = (exam1 + exam2 + exam3) / 3.0let finalGrade = (examAverage * 0.8) + (attendance * 0.2)
print("Exam average: \(examAverage)") // Output: Exam average: 85.0print("Final grade: \(finalGrade)") // Output: Final grade: 87.0
// Determine letter gradelet letterGrade: Stringif finalGrade >= 90 { letterGrade = "A"} else if finalGrade >= 80 { letterGrade = "B"} else if finalGrade >= 70 { letterGrade = "C"} else if finalGrade >= 60 { letterGrade = "D"} else { letterGrade = "F"}
print("Letter grade: \(letterGrade)") // Output: Letter grade: B
// Check if passedlet hasPassed = finalGrade >= 60 && attendance >= 75if hasPassed { print("Congratulations! You passed!") // Output: Congratulations! You passed!}Example 3: User Authentication System
// User input simulationlet username: String? = "admin"let password: String? = "secure123"let isEmailVerified: Bool = truelet isBanned: Bool = falselet loginAttempts: Int = 2let maxAttempts: Int = 3
// Validationlet hasValidUsername = (username ?? "").count >= 3let hasValidPassword = (password ?? "").count >= 8let isAccountActive = !isBannedlet hasAttemptsLeft = loginAttempts < maxAttempts
// Check all conditionsif hasValidUsername && hasValidPassword && isEmailVerified && isAccountActive && hasAttemptsLeft { print("Login successful!") print("Welcome, \(username ?? "User")!")} else { if !hasValidUsername { print("Invalid username") } if !hasValidPassword { print("Password too short") // Output: Password too short } if !isEmailVerified { print("Please verify your email") } if isBanned { print("Account banned") } if !hasAttemptsLeft { print("Too many login attempts") }}Example 4: Temperature Converter
let celsius: Double = 25.0
// Convert to Fahrenheitlet fahrenheit = (celsius * 9.0 / 5.0) + 32.0print("\(celsius)°C = \(fahrenheit)°F")// Output: 25.0°C = 77.0°F
// Convert to Kelvinlet kelvin = celsius + 273.15print("\(celsius)°C = \(kelvin)K")// Output: 25.0°C = 298.15K
// Temperature statuslet status: Stringif celsius <= 0 { status = "Freezing"} else if celsius > 0 && celsius <= 15 { status = "Cold"} else if celsius > 15 && celsius <= 25 { status = "Comfortable"} else { status = "Hot"}
print("Status: \(status)") // Output: Status: ComfortableCommon Pitfalls and Best Practices
✅ Best Practices
-
Use meaningful variable names with operators
// Goodlet totalPrice = itemPrice + shippingCost// Avoidlet t = p + s -
Use parentheses for clarity
// Goodlet result = (a + b) * (c - d)// Less clearlet result = a + b * c - d -
Prefer nil-coalescing over force unwrapping
// Goodlet name = optionalName ?? "Guest"// Dangerouslet name = optionalName! -
Use compound assignment operators
// Goodcount += 1// Verbosecount = count + 1
❌ Common Mistakes
-
Integer division truncation
let result = 5 / 2 // 2 (not 2.5!)let correct = 5.0 / 2.0 // 2.5 -
Comparison operator confusion
let x = 5// if x = 10 { // ❌ Assignment, not comparison!if x == 10 { // ✅ Correct comparisonprint("x is 10")} -
Logical operator short-circuit
// Second condition not evaluated if first is falseif false && expensiveFunction() {// expensiveFunction() is never called} -
Mixing types without conversion
let integer = 5let double = 2.5// let sum = integer + double // ❌ Error!let sum = Double(integer) + double // ✅ Correct
Summary
In this chapter, you learned about:
- ✅ Arithmetic Operators:
+,-,*,/,%for mathematical operations - ✅ Comparison Operators:
==,!=,<,>,<=,>=for comparing values - ✅ Logical Operators:
&&,||,!for Boolean logic - ✅ Range Operators:
...and..<for creating sequences - ✅ Nil-Coalescing Operator:
??for providing default values - ✅ Compound Assignment:
+=,-=,*=,/=,%=for shortcuts - ✅ Operator Precedence: Understanding evaluation order
- ✅ Best Practices: Writing clear and maintainable code
Operators are fundamental to Swift programming. Understanding how to use them effectively will make your code more expressive and powerful.
What’s Next?
Now that you’ve mastered operators, you’re ready to learn about:
Topic 5: Strings and Characters
- String creation and manipulation
- String interpolation
- Multi-line strings
- String methods and properties
- Character operations
Keep practicing with operators, and try combining them in different ways to solve problems! 🚀
Practice Exercise:
Try creating programs that:
- Build a BMI calculator using arithmetic operators
- Create an age verification system using comparison and logical operators
- Slice an array using range operators
- Handle user input with nil-coalescing operator
Happy coding! 💻