Declarations
A declaration introduces a new name into your program — a constant, type, function, protocol, operator, and so on. This reference gives a concise overview of every declaration kind in Swift 6 and the modifiers that adjust them.
Top-level code and imports
Each source file holds top-level declarations. Most files
contain only declarations, but main.swift (and a file marked
@main) may also contain top-level executable statements. An
import declaration brings another module's symbols
into scope, optionally narrowing to a single symbol.
import Foundation
import struct SwiftUI.Color // import a single symbol
Constants, variables, and type aliases
let declares an immutable binding;
var a mutable one. Variable declarations also host
computed properties, observers (willSet/didSet), and
property wrappers. A typealias gives an existing
type a new name and may be generic.
let maxRetries = 3
var area: Double { width * height } // computed
typealias Handler = (Result<Data, Error>) -> Void
Functions
A func declaration names parameters (with argument
labels), a return type, and a body. Functions may be async,
throws (including typed throws), generic, variadic, and may take
inout parameters or default values. Operators are declared as
functions too.
func fetch(_ url: URL, retries: Int = 3) async throws -> Data { ... }
Type declarations
Swift's four nominal type kinds:
| Keyword | Semantics | Notes |
|---|---|---|
enum | Value type | Cases, associated/raw values, indirect |
struct | Value type | Memberwise init, copy-on-assign |
class | Reference type | Inheritance, deinit, identity |
actor | Reference type | Protects mutable state for concurrency |
actor Counter {
private var value = 0
func increment() { value += 1 }
}
Protocols
A protocol declares a set of requirements —
properties, methods, initializers, subscripts, and associated types
(associatedtype) — that conforming types must satisfy. Protocols may
inherit other protocols, be constrained to classes (AnyObject), and
provide default implementations through protocol extensions.
Members: initializers, deinitializers, subscripts
An init sets up a new instance (designated,
convenience, failable, or required). A deinit
runs when a class instance is deallocated (classes only). A
subscript declares element access with
[], including static subscript.
Extensions
An extension adds computed properties, methods,
initializers, subscripts, nested types, and protocol conformances to an existing
type — including conditional conformance via a where clause.
extension Array where Element: Numeric {
func sum() -> Element { reduce(0, +) }
}
Operators and precedence groups
An operator declaration introduces a custom
prefix, infix, or postfix operator; an
infix operator names a precedencegroup that defines
its relative precedence and associativity. The operator's behavior is then given
by a static operator function.
infix operator .^ : MultiplicationPrecedence
precedencegroup ExponentPrecedence {
higherThan: MultiplicationPrecedence
associativity: right
}
Declaration modifiers
Modifiers refine a declaration. Common ones include access levels
(open, public, package,
internal, fileprivate, private),
type-level membership (static, class),
final, override, lazy,
mutating/nonmutating, convenience,
required, dynamic, weak/unowned,
and concurrency modifiers like nonisolated and
isolated.
Note: attributes (written with @, like
@MainActor or @available) are distinct from modifiers
and are covered on the next page.
Summary
Declarations are how you populate a Swift program with named entities: imports
and top-level code set up a file; let/var/func
and the four type kinds form its substance; protocols, extensions, and operators
add abstraction and expressiveness; and modifiers tune visibility and behavior.