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:

KeywordSemanticsNotes
enumValue typeCases, associated/raw values, indirect
structValue typeMemberwise init, copy-on-assign
classReference typeInheritance, deinit, identity
actorReference typeProtects 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.