Beginner

Operators in Swift

Learn arithmetic, comparison, logical, and Swift-specific operators like nil-coalescing, ranges, and overflow operators with Docker-ready examples

Operators are the symbols that let you compute, compare, and combine values. Swift inherits the familiar C-family operators but layers its safety-first philosophy on top of them: operators are strongly typed, will not silently coerce between number types, and trap on overflow by default rather than wrapping around quietly.

Because Swift is a multi-paradigm language with static, strong, inferred typing, the type of an expression is determined at compile time. An operator like + works on Int and on Double, but you cannot add an Int to a Double without converting one of them first — the compiler refuses to guess. This tutorial walks through arithmetic, comparison, and logical operators, then covers the operators that make Swift distinct: compound assignment, the ternary conditional, the nil-coalescing operator (??), range operators, overflow operators, and identity operators.

Everything below runs as a plain .swift script, so you can test each example with a single Docker command.

Arithmetic Operators

Swift provides the standard arithmetic operators. Note that integer division truncates toward zero, and there is no built-in exponentiation operator (you would use pow from Foundation for that).

Create a file named operators_arithmetic.swift:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
let a = 17
let b = 5

print("Sum:        \(a + b)")   // addition
print("Difference: \(a - b)")   // subtraction
print("Product:    \(a * b)")   // multiplication
print("Quotient:   \(a / b)")   // integer division truncates
print("Remainder:  \(a % b)")   // modulo

// Floating-point division keeps the fractional part
let x = 17.0
let y = 5.0
print("Float quotient: \(x / y)")

// Unary minus negates a value
print("Negation: \(-a)")

Because a and b are both Int, a / b performs integer division and discards the fractional part. Switching to Double literals (17.0, 5.0) gives a true floating-point result.

Comparison and Logical Operators

Comparison operators return a Bool, and the logical operators (&&, ||, !) combine those booleans. Swift’s && and || short-circuit, meaning the right-hand side is only evaluated if needed.

Create a file named operators_logical.swift:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
let temperature = 22
let isRaining = false

// Comparison operators each produce a Bool
print("Above 18?  \(temperature > 18)")
print("Equal 22?  \(temperature == 22)")
print("Not 30?    \(temperature != 30)")

// Logical AND, OR, and NOT
let niceWeather = temperature > 18 && !isRaining
print("Nice weather: \(niceWeather)")

let stayInside = isRaining || temperature < 10
print("Stay inside:  \(stayInside)")

The ! operator inverts a boolean, so !isRaining is true when isRaining is false.

Assignment, Ternary, Nil-Coalescing, and Ranges

This example collects the operators that give Swift its expressive, concise feel. Compound assignment operators (+=, -=, *=) update a variable in place. The ternary operator (condition ? a : b) chooses between two values. The nil-coalescing operator (??) supplies a default when an optional is nil — a direct expression of Swift’s optionals safety model. Range operators build sequences for iteration.

Create a file named operators_swift_specific.swift:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// String concatenation with +
var greeting = "Hello"
greeting += ", Swift!"
print(greeting)

// Compound assignment updates in place
var score = 100
score -= 25
score *= 2
print("Score: \(score)")

// Ternary conditional operator
let age = 20
let category = age >= 18 ? "Adult" : "Minor"
print("Category: \(category)")

// Nil-coalescing: use a default when the optional is nil
let nickname: String? = nil
let displayName = nickname ?? "Anonymous"
print("Name: \(displayName)")

// Range operators drive iteration
for i in 1...3 {
    print("Closed range: \(i)")
}
for i in 0..<3 {
    print("Half-open range: \(i)")
}

The closed range 1...3 includes both endpoints, while the half-open range 0..<3 excludes the upper bound — a distinction that maps cleanly onto zero-based array indices.

Precedence, Overflow, and Identity

Operators follow precedence rules (* binds tighter than +), and parentheses override them. Swift also adds overflow operators (&+, &-, &*) that intentionally wrap around instead of trapping, which is useful for low-level bit manipulation. The identity operators (===, !==) test whether two references point to the same class instance, distinct from == which tests value equality.

Create a file named operators_precedence.swift:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// Multiplication has higher precedence than addition
print("2 + 3 * 4 = \(2 + 3 * 4)")

// Parentheses change the grouping
print("(2 + 3) * 4 = \((2 + 3) * 4)")

// Overflow operator wraps instead of trapping
let maxByte: UInt8 = 255
print("255 &+ 1 = \(maxByte &+ 1)")

// Identity operators compare references, not values
class Robot {}
let r1 = Robot()
let r2 = r1
print("Same instance: \(r1 === r2)")

Without the overflow operator, maxByte + 1 would crash at runtime because 255 is the maximum value of a UInt8. The &+ operator opts into wraparound, producing 0.

Running with Docker

Run each example with the official Swift image — no local toolchain required.

1
2
3
4
5
6
7
8
# Pull the official image
docker pull swift:6.0

# Run each example
docker run --rm -v $(pwd):/app -w /app swift:6.0 swift operators_arithmetic.swift
docker run --rm -v $(pwd):/app -w /app swift:6.0 swift operators_logical.swift
docker run --rm -v $(pwd):/app -w /app swift:6.0 swift operators_swift_specific.swift
docker run --rm -v $(pwd):/app -w /app swift:6.0 swift operators_precedence.swift

Expected Output

operators_arithmetic.swift:

Sum:        22
Difference: 12
Product:    85
Quotient:   3
Remainder:  2
Float quotient: 3.4
Negation: -17

operators_logical.swift:

Above 18?  true
Equal 22?  true
Not 30?    true
Nice weather: true
Stay inside:  false

operators_swift_specific.swift:

Hello, Swift!
Score: 150
Category: Adult
Name: Anonymous
Closed range: 1
Closed range: 2
Closed range: 3
Half-open range: 0
Half-open range: 1
Half-open range: 2

operators_precedence.swift:

2 + 3 * 4 = 14
(2 + 3) * 4 = 20
255 &+ 1 = 0
Same instance: true

Key Concepts

  • Strong typing, no implicit coercion — Swift will not mix Int and Double in an arithmetic expression; you must convert explicitly, which prevents silent precision bugs.
  • Integer division truncates17 / 5 yields 3; use floating-point operands when you need the fractional result.
  • Overflow traps by default — ordinary arithmetic crashes on overflow for safety; the opt-in &+, &-, &* operators wrap around when you genuinely want that behavior.
  • Nil-coalescing (??) — a concise, safe way to provide a fallback for optionals, central to Swift’s null-safety design.
  • Ternary operatorcondition ? a : b chooses a value inline, keeping simple branching expressive.
  • Range operators... is inclusive of both bounds, ..< excludes the upper bound, mapping naturally to array indices and loops.
  • == vs === — value equality compares contents, while identity (===) checks whether two references are the same class instance.
  • Precedence and short-circuiting* binds tighter than +, parentheses override grouping, and &&/|| skip evaluating the right side when the result is already determined.

Running Today

All examples can be run using Docker:

docker pull swift:6.0
Last updated:

Comments

Loading comments...

Leave a Comment

2000 characters remaining