Swift Compiled language and SwiftPM

Version 6.4 · source

Start here

swift --version
Check the toolchain
swift package init --type executable
New CLI project
swift build
Compile
swift run
Build and run
swift test
Run tests
swift repl
Interactive prompt
swiftc <file>.swift -o <out>
Compile one file
swift package resolve
Fetch dependencies

Concepts

  1. Package.swift manifest
  2. Sources/ targets
  3. .build/ binaries
  4. Output your program

Toolchain

swift --version
Show Swift version
swift <file>.swift
Run a script directly
swiftc <file>.swift -o <out>
Compile to an executable
swiftc -O <file>.swift
Optimized build
swift repl
Start the REPL
swift run <target> <args>
Run a named executable with args
swift build -c release
Optimized release build
swift build --show-bin-path
Print the output directory
swift test --filter <name>
Run matching tests only
swift test --parallel
Run tests in parallel

Package manager

swift package init --name <name> --type executable
Create an executable package
swift package init --type library
Create a library package
swift package resolve
Resolve and fetch dependencies
swift package update
Update to newest allowed versions
swift package clean
Remove build artifacts
swift package reset
Reset caches and checkouts
swift package show-dependencies
Print the dependency tree
swift package describe
Describe the package
swift package edit <dep>
Work on a dependency locally
.package(url: "<url>", from: "1.0.0")
Declare a dependency
.executableTarget(name: "<name>")
Declare an executable target
.testTarget(name: "<name>Tests", dependencies: ["<name>"])
Declare a test target
// swift-tools-version: 6.0
First line of Package.swift

Basics

let x = 1
Constant
var x = 1
Variable
let x: Double = 1
Explicit type
"Hi \(name)"
String interpolation
let (a, b) = (1, 2)
Destructure a tuple
let r = 1...5
Closed range
1..<5
Half-open range
for i in 0..<n { }
Loop over a range
while <cond> { }
While loop
if <cond> { } else { }
Conditional
switch x { case 1: ... default: ... }
Pattern match, must be exhaustive
case 1...5, 10:
Several patterns per case
func f(_ a: Int, b: Int = 0) -> Int { }
Function with labels
f(1, b: 2)
Call with argument label
let s = """..."""
Multiline string
print(x)
Print a value

Optionals

var x: Int? = nil
Optional value
if let v = x { }
Unwrap if present
guard let v = x else { return }
Early exit unwrap
x ?? <default>
Fallback value
x?.count
Optional chaining
x!
Force unwrap (crashes on nil)
if let x { }
Shorthand unwrap
x.map { $0 + 1 }
Transform if present

Collections

let a = [1, 2, 3]
Array literal
a.append(4)
Add an element
a[0]
Subscript
a.count / a.isEmpty
Size checks
let d = ["k": 1]
Dictionary literal
d["k"]
Lookup returns an optional
let s: Set = [1, 2]
Set
a.map { $0 * 2 }
Transform elements
a.filter { $0 > 1 }
Keep matches
a.reduce(0, +)
Fold to a value
a.sorted()
Sorted copy
a.compactMap { Int($0) }
Map and drop nils
for (i, v) in a.enumerated() { }
Index and value

Types

struct P { var x: Int }
Value type
class C { var x = 0 }
Reference type
enum D { case n, s }
Enumeration
case some(Int)
Enum case with payload
protocol Shape { func area() -> Double }
Protocol
extension P: Shape { }
Conform in an extension
init(x: Int) { self.x = x }
Initializer
mutating func inc() { }
Mutate a struct
var area: Double { w * h }
Computed property
final class C { }
Class that cannot be subclassed
struct Box<T> { var v: T }
Generic type
func f<T: Comparable>(_ a: T) { }
Generic function
{ (a: Int) -> Int in a * 2 }
Closure
@escaping
Closure outlives the call

Errors and async

func f() throws -> Int
Function that can throw
do { try f() } catch { }
Handle an error
try? f()
Optional result on failure
try! f()
Crash on failure
throw MyError.bad
Throw an error
enum MyError: Error { case bad }
Define an error type
defer { <cleanup> }
Run on scope exit
func f() async -> Int
Async function
await f()
Call an async function
Task { await f() }
Start async work
async let a = f()
Run child tasks in parallel
withTaskGroup(of: Int.self) { g in }
Dynamic task group
actor Counter { }
Isolate mutable state
@MainActor
Run on the main actor
@main struct App { static func main() }
Program entry point

Recipes

New CLI project
swift package init --name hello --type executablecd helloswift run
Add a dependency
# Package.swiftdependencies: [  .package(url: "https://github.com/apple/swift-argument-parser", from: "1.3.0")],# then: swift build
Release build and test
swift testswift build -c release.build/release/<name>
Quick script
echo 'print("hi")' > t.swiftswift t.swift