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,SetandStringare 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.
| Syntax | Meaning | When the value is nil |
|---|---|---|
let x: Int? = nil | Declares an optional | It is simply absent |
x! | Force unwrap | Crash at runtime |
x ?? 0 | Nil coalescing | Uses the default |
if let y = x | Optional binding in an if | Branch is skipped |
guard let y = x else { return } | Bind or leave the scope | Runs the else block, no nesting |
x?.count | Optional chaining | The whole expression is nil |
x as? String | Conditional cast | nil 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.Related
Structs, classes and protocols Closures and error handling
Last refreshed 2026-09-18.