# Swift Cheat Sheet: Syntax, Optionals, Protocols and async

Source: https://srvscripts.com/guides/swift-cheat-sheet/
Updated: 2026-10-09
Publisher: srvScripts (https://srvscripts.com/)

**Short answer:** Create a command-line project with `swift package init --type executable` and run it with `swift run`. Use `let` for constants and `var` for variables, unwrap optionals with `if let`, `guard let` or `??`, and prefer `struct` (value type) over `class`. Model states with `enum` and `switch`, mark failing functions `throws` and call them with `try`. Swift 6 checks data races at compile time; use `async`/`await`, `Task` and `actor` for concurrent code.

The examples in this Swift cheat sheet were run with Swift 6.4 (swift-6.4-RELEASE) on Ubuntu 24.04 on 9 October 2026, using Swift Package Manager and Foundation on Linux.

## Swift Package Manager and toolchain

| Command | What it does |
| --- | --- |
| swift --version | Show the compiler version |
| swift package init --type executable | New command-line package in the current directory |
| swift package init --type library | New library package |
| swift run / swift run Demo --flag | Build and run (with arguments) |
| swift build -c release | Optimised binary in .build/release/ |
| swift test | Run tests (new packages use the Swift Testing library, @Test and #expect) |
| swift package update | Update dependencies within Package.swift rules |
| swiftc main.swift -o app | Compile a single file without a package |
| swiftly install latest | Install or switch toolchains with swiftly, the installer swift.org recommends on Linux |

On Linux, Swift ships with Foundation, so `String(contentsOfFile:)`, `JSONEncoder`, `ProcessInfo` and `Process` work as they do on macOS. Apple frameworks such as UIKit and SwiftUI are not available there.

## Variables, strings and control flow

| Syntax | What it does | Example |
| --- | --- | --- |
| let | Constant; prefer it by default | let name = "web01" |
| var | Variable | var port = 443; port += 1 |
| Type annotation | Optional when the type can be inferred | let ratio: Double = 0.75 |
| "\(expr)" | String interpolation | "\(name):\(port)" |
| """ ... """ | Multi-line string; indentation of the closing quotes is removed |  |
| 0.. String {
    "Hello \(person) from \(city)"     // single expression: implicit return
}
greet("Ali")                 // argument label omitted with _
greet("Sam", from: "York")

func bump(_ x: inout Int) { x += 1 }
var c = 1
bump(&c)                     // c == 2
```

## Structs, classes, enums and protocols

```
struct Server: Codable, Equatable {
    var name: String
    var port: Int = 22
    var address: String { "\(name):\(port)" }       // computed property
    mutating func setPort(_ p: Int) { port = p }
}

enum Event {
    case login(user: String, ok: Bool)
    case restart(String)
    case quit
}

switch event {
case .login(let user, false): print("failed login \(user)")
case .login(let user, _):     print("login \(user)")
case .restart(let svc):       print("restart \(svc)")
case .quit:                   print("quit")
}

protocol Check {
    var name: String { get }
    func healthy() -> Bool
}
extension Check {
    func healthy() -> Bool { true }       // default implementation
}
extension Server: Check {}                // Server already has `name`
```

| Syntax | Meaning |
| --- | --- |
| struct | Value type: copied on assignment |
| final class | Reference type: assignments share one instance |
| enum Level: Int, CaseIterable | Raw values and Level.allCases |
| func report(_ c: some Check) | Opaque generic parameter (static dispatch) |
| let checks: [any Check] | Existential: mixed types behind one protocol |
| func largest(_ xs: [T]) -> T? | Generic function with a constraint |
| try JSONEncoder().encode(server) | JSON from a Codable type |

## Error handling

```
enum ConfigError: Error {
    case missing(String)
    case badPort(String)
}

func parsePort(_ s: String) throws(ConfigError) -> Int {      // typed throws
    guard !s.isEmpty else { throw .missing("port") }
    guard let p = Int(s), (1...65535).contains(p) else { throw .badPort(s) }
    return p
}

do {
    let p = try parsePort("70000")
    print(p)
} catch .badPort(let raw) {
    print("bad port \(raw)")        // bad port 70000
} catch {
    print("other: \(error)")
}
```

| Syntax | What it does |
| --- | --- |
| throws / throws(MyError) | Function can throw any error / one error type |
| try f() | Call a throwing function inside do or another throwing function |
| try? f() | Returns nil on error |
| try! f() | Crashes on error |
| Result { try f() } | Capture success or failure as a value |
| defer { ... } | Run cleanup when the scope exits |

## Concurrency: async, await, tasks and actors

```
func fetchStatus(_ host: String) async -> Int {
    try? await Task.sleep(for: .milliseconds(10))
    return host.count
}

actor HitCounter {                    // serialises access to its state
    private var hits = 0
    func add() { hits += 1 }
    func value() -> Int { hits }
}

async let a = fetchStatus("web01")    // runs concurrently
async let b = fetchStatus("web02")
let both = await [a, b]

let results = await withTaskGroup(of: Int.self) { group in
    for h in ["a", "bb", "ccc"] {
        group.addTask { await fetchStatus(h) }
    }
    var out: [Int] = []
    for await v in group { out.append(v) }
    return out
}
```

Packages with `swift-tools-version: 6.0` or later use the Swift 6 language mode, which turns data-race warnings into errors. Values sent between tasks must be `Sendable`; structs and enums of `Sendable` members qualify automatically. The migration guide explains how to adopt this in older code.

## Files, processes and a log example

For server admins: count requests per client IP in an access log with Foundation.

```
import Foundation

let path = CommandLine.arguments.dropFirst().first ?? "/var/log/nginx/access.log"
guard let text = try? String(contentsOfFile: path, encoding: .utf8) else {
    FileHandle.standardError.write(Data("cannot read \(path)\n".utf8))
    exit(1)
}

var hits: [Substring: Int] = [:]
for line in text.split(separator: "\n") {
    if let ip = line.split(separator: " ").first {
        hits[ip, default: 0] += 1
    }
}
for (ip, n) in hits.sorted(by: { $0.value > $1.value }).prefix(10) {
    print(String(format: "%7d", n), ip)
}
```

| Syntax | What it does |
| --- | --- |
| try String(contentsOfFile: p, encoding: .utf8) | Read a whole text file |
| try text.write(toFile: p, atomically: true, encoding: .utf8) | Write a file |
| FileManager.default.fileExists(atPath: p) | Check a path |
| ProcessInfo.processInfo.environment["HOME"] | Environment variable |
| let p = Process(); p.executableURL = URL(fileURLWithPath: "/usr/bin/uptime"); try p.run() | Run a program; call p.waitUntilExit() to wait |

**Official documentation (checked 9 October 2026):** [The Swift Programming Language](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/) · [Swift Standard Library](https://developer.apple.com/documentation/swift/) · [Install Swift on Linux](https://www.swift.org/install/linux/) · [Swift Package Manager](https://www.swift.org/documentation/package-manager/) · [Swift 6 Migration Guide (data-race safety)](https://www.swift.org/migration/documentation/migrationguide/) · [Swift 6.4 Released](https://www.swift.org/blog/swift-6.4-released/)

## Swift Cheat Sheet at a glance

In short: A compact Swift 6.4 reference covering SwiftPM, optionals, collections, closures, types, protocols, error handling and concurrency, on macOS or Linux.

Swift Cheat Sheet: what this guide covers.

**Related guides:** [Kotlin Cheat Sheet: Syntax, Null Safety and Collections](https://srvscripts.com/guides/kotlin-cheat-sheet/) · [Dart 3 Cheat Sheet: Null Safety, Records, Patterns and async](https://srvscripts.com/guides/dart-cheat-sheet/) · [TypeScript Cheat Sheet: Types, Generics and tsconfig](https://srvscripts.com/guides/typescript-cheat-sheet/).
