Basic Operators
An operator is a symbol or phrase you use to check, change, or combine values. Swift's operators feel familiar from other C-family languages but are tightened up for safety: assignment returns nothing, arithmetic doesn't silently overflow, and there are purpose-built operators for optionals and ranges. This chapter walks through all of them.
Terminology
Operators come in three shapes, defined by how many values (operands) they act on:
- Unary operators act on a single value, either as a prefix (
-a,!b) or a postfix (c!). - Binary operators act on two values and sit between them (
a + b); these are infix. - Ternary operators act on three values. Swift has exactly one: the ternary conditional operator
a ? b : c.
The assignment operator
The assignment operator = initializes or updates a value. You can decompose a tuple in a single assignment. Unlike C, Swift's assignment does not itself return a value, which prevents the classic bug of writing = where you meant ==.
let b = 10
var a = 5
a = b // a is now 10
let (x, y) = (1, 2) // x = 1, y = 2
// if x = y { ... } // error: assignment doesn't return a value
Arithmetic operators
The four standard arithmetic operators — addition +, subtraction -, multiplication *, and division / — work on all number types. Unlike C, they don't allow values to overflow by default; an overflow traps at runtime rather than wrapping silently. (Use the overflow operators from the Advanced Operators chapter when you want wrapping.)
let sum = 1 + 2 // → 3
let diff = 5 - 3 // → 2
let product = 2 * 3 // → 6
let quotient = 10 / 3 // → 3 (integer division truncates)
let exact = 10.0 / 3.0 // → 3.333...
The + operator is also overloaded to concatenate strings: "hello, " + "world".
Remainder operator
The remainder operator % works out how many multiples of one number fit inside another and returns what's left over. It works with negative values too — the sign follows the first operand.
let r1 = 9 % 4 // → 1
let r2 = -9 % 4 // → -1
let r3 = 8 % 2 // → 0 (even number check)
// Floating-point remainder uses the method form:
let r4 = (8.0).truncatingRemainder(dividingBy: 2.5) // → 0.5
Unary minus and plus
The unary minus operator - toggles a value's sign. The unary plus + returns its operand unchanged — it exists only for symmetry, to make code read clearly when you want to emphasize positivity.
let three = 3
let minusThree = -three // → -3
let plusThree = -minusThree // → 3
let alsoSix = +6 // → 6
Compound assignment operators
Compound assignment combines an operation with assignment — +=, -=, *=, /=, and so on — so a += 2 is shorthand for a = a + 2. Like plain assignment, these don't return a value.
var score = 10
score += 5 // → 15
score -= 3 // → 12
score *= 2 // → 24
Comparison operators
Comparison operators return a Bool: equal ==, not equal !=, greater than >, less than <, greater-than-or-equal >=, and less-than-or-equal <=. You can compare tuples of the same type and arity; they compare element by element, left to right.
print(1 == 1) // → true
print(2 != 1) // → true
print("abc" < "abd") // → true
// Tuples compare element by element
print((1, "zebra") < (2, "apple")) // → true (1 < 2)
print((3, "apple") < (3, "bird")) // → true (3 == 3, "apple" < "bird")
Ternary conditional operator
The ternary conditional question ? answerA : answerB evaluates to answerA if the question is true and answerB otherwise. It's a compact alternative to a small if/else — useful for picking one of two values, but keep it readable.
let contentHeight = 40
let hasHeader = true
let rowHeight = contentHeight + (hasHeader ? 50 : 20)
print(rowHeight) // → 90
Nil-coalescing operator
The nil-coalescing operator a ?? b unwraps an optional a if it has a value, and otherwise returns the default b. It's shorthand for a != nil ? a! : b, and the right-hand side is only evaluated if needed. The type of b must match the type stored inside the optional a.
let defaultColor = "red"
var userColor: String? = nil
var chosen = userColor ?? defaultColor
print(chosen) // → red
userColor = "green"
chosen = userColor ?? defaultColor
print(chosen) // → green
Range operators
Swift provides three range operators for expressing a span of values — invaluable in loops and collection slicing.
Closed range
The closed range operator a...b includes both endpoints. It requires a <= b.
for index in 1...5 {
print(index) // → 1, 2, 3, 4, 5
}
Half-open range
The half-open range operator a..<b includes a but not b — ideal for iterating over zero-based collection indices.
let names = ["Anna", "Alex", "Brian", "Jack"]
for i in 0..<names.count {
print("Person \(i + 1) is \(names[i])")
}
// → Person 1 is Anna ... Person 4 is Jack
One-sided ranges
Omit one endpoint to get a one-sided range — useful for slicing from or to a position. A one-sided range that has no end can't be iterated without a terminating condition.
let names = ["Anna", "Alex", "Brian", "Jack"]
print(names[2...]) // → ["Brian", "Jack"]
print(names[...1]) // → ["Anna", "Alex"]
print(names[..<2]) // → ["Anna", "Alex"]
Logical operators
Logical operators combine or invert Boolean values. There are three: NOT !a, AND a && b, and OR a || b. AND and OR are short-circuiting: they evaluate the right operand only when the result isn't already decided by the left.
let allowedEntry = false
if !allowedEntry {
print("ACCESS DENIED") // → ACCESS DENIED
}
let enteredDoorCode = true
let passedRetinaScan = false
let hasKey = true
if (enteredDoorCode && passedRetinaScan) || hasKey {
print("Welcome!") // → Welcome! (hasKey is true)
}
Tip: Logical operators are left-associative. When combining && and ||, add explicit parentheses to make precedence obvious to readers, even where Swift's rules already produce the result you want.
Wrapping up
You've covered the full set of basic operators: assignment, the arithmetic and remainder operators, comparisons, the ternary conditional, nil-coalescing for optionals, the three range operators, and the logical operators. With values and operators in hand, the next chapter dives into one of Swift's richest value types: strings and characters.