Syntax and optionals

let and var, functions and control flow, and the optional type that forces you to decide what happens when a value is missing.

Values, functions, control flow

let name = "Ada"            // constant, type inferred as String
var score = 0               // variable
let ratio: Double = 0.75    // explicit type when it is not obvious

func greet(_ who: String, greeting: String = "Hello") -> String {
    return greeting + ", " + who
}

greet("Ada")                            // "Hello, Ada"
greet("Ada", greeting: "Welcome")       // argument labels are part of the API

let label = score == 0 ? "empty" : "scored"

switch score {
case 0:
    print("nothing yet")
case 1..<50:
    print("getting there")
default:
    print("good")
}

for i in stride(from: 1, through: 5, by: 2) { print(i) }   // 1 3 5
  • Prefer let; a value that never changes cannot be changed by a later edit either.
  • Argument labels are part of the function's name, which is why Swift call sites read like sentences. Use _ to omit one where it adds nothing.
  • Value types such as Array, Dictionary, Set and String are copied on assignment, so mutating a copy never touches the original.

Optionals

An optional is a value that may be absent, written with a trailing ?. Swift will not let you use it until you have unwrapped it, which moves the missing-value problem from a runtime crash to a compile error.

SyntaxMeaningWhen the value is nil
let x: Int? = nilDeclares an optionalIt is simply absent
x!Force unwrapCrash at runtime
x ?? 0Nil coalescingUses the default
if let y = xOptional binding in an ifBranch is skipped
guard let y = x else { return }Bind or leave the scopeRuns the else block, no nesting
x?.countOptional chainingThe whole expression is nil
x as? StringConditional castnil instead of a crash
struct User {
    let email: String
    let phone: String?
}

func contact(_ user: User?) -> String {
    guard let email = user?.email, !email.isEmpty else { return "unknown" }
    let phone = user?.phone ?? "no phone"
    return email + " / " + phone
}

let maybe: Int? = Int("42")        // Int("abc") would be nil, not a crash
if let value = maybe, value > 40 {
    print(value)
}

// map transforms the wrapped value, and the result stays optional
let doubled: Int? = maybe.map { $0 * 2 }
⚠️
Every ! is an unchecked claim that the value exists. In production prefer guard let, ?? or a throwing initialiser; a force unwrap on a value that came from a network response or user input is a crash waiting for the right input.

FAQ

if let or guard let?
guard let when the rest of the function cannot proceed without the value — it keeps the happy path unindented. if let when only one branch needs the value.
What does implicitly unwrapped optional mean?
A type written String! behaves like an optional but is auto-unwrapped on use. It exists for outlets and framework callbacks; it still crashes if read while nil, so treat it as a convenience, not a safety waiver.

Structs, classes and protocols Closures and error handling

Last refreshed 2026-09-18.