Swift
01 / 05

Language Basics

Swift: Language Basics

Swift is Apple's modern, type-safe language for iOS, macOS, watchOS, and tvOS. It emphasizes safety, performance, and expressive syntax. Swift uses ARC (Automatic Reference Counting) for memory management.

Variables, Constants & Types

// Constants (prefer let by default)
let name = "Alice"          // type inferred: String
let age: Int = 30
let pi: Double = 3.14159

// Variables
var score = 0
score += 10

// Type aliases
typealias UserID = UUID

// Optionals — a value or nil
var nickname: String? = nil
nickname = "ally"

// Unwrapping optionals
if let nick = nickname {
    print("Nickname: \(nick)")
}

// Optional chaining
let upper = nickname?.uppercased()   // String? — nil if nickname is nil

// Nil coalescing
let display = nickname ?? "Anonymous"

// Guard — early exit
func greet(_ name: String?) {
    guard let name = name else { return }
    print("Hello, \(name)!")
}

// Force unwrap (use sparingly — crashes on nil)
let forced = nickname!

Collections

// Array
var fruits = ["apple", "banana", "cherry"]
fruits.append("date")
fruits.insert("avocado", at: 0)
fruits.remove(at: 1)
fruits.count         // Int
fruits.first         // String? (optional)
fruits.contains("cherry")  // Bool
let sorted = fruits.sorted()
let upper = fruits.map { $0.uppercased() }
let long = fruits.filter { $0.count > 5 }

// Dictionary
var scores: [String: Int] = ["Alice": 95, "Bob": 82]
scores["Carol"] = 91
scores["Bob"]          // Int? — optional
scores["Bob", default: 0]  // Int — non-optional with default
scores.keys            // Dictionary.Keys
for (name, score) in scores { }

// Set
var tags: Set<String> = ["swift", "ios", "apple"]
tags.insert("xcode")
tags.contains("ios")   // true
let union = tags.union(["macos", "swift"])

Control Flow & Pattern Matching

// Switch — must be exhaustive, no fallthrough by default
switch score {
case 90...100:
    print("A")
case 80..<90:
    print("B")
case let n where n < 0:
    print("Invalid: \(n)")
default:
    print("C or below")
}

// For-in loops
for i in 1...5 { print(i) }
for i in stride(from: 0, to: 10, by: 2) { }  // 0, 2, 4, 6, 8

// Tuples
let coordinates = (x: 3.0, y: 4.0)
print(coordinates.x)   // 3.0
let (x, y) = coordinates

// Enums with associated values
enum Result<T> {
    case success(T)
    case failure(Error)
}

enum Direction {
    case north, south, east, west

    var opposite: Direction {
        switch self {
        case .north: return .south
        case .south: return .north
        case .east: return .west
        case .west: return .east
        }
    }
}

let dir = Direction.north
if case .north = dir { print("Going north") }

Functions & Closures

// Functions
func add(_ a: Int, to b: Int) -> Int {   // external: _, internal: a
    return a + b
}
add(3, to: 4)   // named parameter syntax

// Multiple return values
func minMax(_ array: [Int]) -> (min: Int, max: Int) {
    return (array.min()!, array.max()!)
}
let result = minMax([3, 1, 4, 1, 5])
result.min   // 1

// Closures
let multiply = { (a: Int, b: Int) -> Int in a * b }
multiply(3, 4)   // 12

// Trailing closure syntax
[1, 2, 3].forEach { print($0) }
let doubled = [1, 2, 3].map { $0 * 2 }

// @escaping — closure called after function returns
func fetchData(completion: @escaping (Data?) -> Void) {
    URLSession.shared.dataTask(with: url) { data, _, _ in
        completion(data)
    }.resume()
}

// Higher-order functions
let numbers = [5, 2, 8, 1, 9, 3]
numbers.sorted()                         // [1, 2, 3, 5, 8, 9]
numbers.sorted { $0 > $1 }              // [9, 8, 5, 3, 2, 1]
numbers.reduce(0, +)                     // 28
numbers.compactMap { $0 > 5 ? $0 : nil }  // [8, 9]

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free