Standard Library Overview
|
This section documents the Swift 6 language mode as shipped by Swift 6.3, as published in The Swift Programming Language at docs.swift.org, which is the reference these pages are written and verified against. 6.4-beta-only features are always flagged as such — never presented as baseline. This content was generated with the assistance of AI and should be verified against docs.swift.org before being relied on in production. This section’s bibliography lists the reference material consulted while preparing these pages. |
The Swift module — imported implicitly into every Swift file — is where the language’s built-in types
(Int, String, Array, Optional, …) and the protocols that give them a common vocabulary actually live.
This page is a map of that module: what the core protocol families are for and how they relate, with detail
pages elsewhere covering the types built on top of them in depth.
Numeric Protocols
| Protocol | What it adds |
|---|---|
|
|
|
Integer semantics: division and remainder truncate toward zero, bitwise operators, and conversion between integer types. |
|
Refines |
|
IEEE 754-style semantics: |
|
Narrow a generic parameter to only signed, or only unsigned, numeric types. |
func sum<T: Numeric>(_ values: [T]) -> T {
values.reduce(0, +) // works for Int, Double, Decimal, or any custom Numeric type
}
func isEven<T: BinaryInteger>(_ value: T) -> Bool {
value % 2 == 0 // works for any integer type, signed or unsigned
}
See Advanced Operators for BinaryInteger and
FixedWidthInteger used in bit-manipulation code, and
Generics for constraining type parameters to protocols in
general.
Equatable, Hashable, Comparable, Identifiable
| Protocol | Requirement | Typically |
|---|---|---|
|
|
Synthesized automatically for structs/enums
whose members are all |
|
|
Synthesized alongside |
|
|
Unlocks |
|
|
A stable identity distinct from equality — two values can be
|
struct User: Identifiable, Comparable {
let id: Int
var name: String
static func < (lhs: User, rhs: User) -> Bool {
lhs.name < rhs.name
}
}
let users = [User(id: 2, name: "Bo"), User(id: 1, name: "Ada")]
users.sorted() // sorted by name, via Comparable
Set(users.map(\.id)) // Hashable Int ids, not the User itself
Identifiable is deliberately independent of Equatable/Hashable: a UI list keyed by id can still detect
content changes separately by also conforming to Equatable.
CustomStringConvertible and Friends
| Protocol | Used by |
|---|---|
|
|
|
|
|
Refines |
|
The other direction: a custom destination |
struct Point: CustomStringConvertible {
var x: Double, y: Double
var description: String { "(\(x), \(y))" }
}
print(Point(x: 1, y: 2)) // "(1.0, 2.0)" -- print uses `description` automatically
ExpressibleBy…Literal
A type that conforms to one of these can be constructed directly from a literal in source, with the compiler
inferring which init to call:
struct Fraction: ExpressibleByIntegerLiteral {
var numerator: Int
var denominator: Int = 1
init(integerLiteral value: Int) {
numerator = value
}
}
let half: Fraction = 1 // calls init(integerLiteral:) -- no explicit constructor call
ExpressibleByStringLiteral, ExpressibleByBooleanLiteral, ExpressibleByArrayLiteral,
ExpressibleByDictionaryLiteral and ExpressibleByNilLiteral follow the same shape for their respective literal
forms; Optional’s conformance to `ExpressibleByNilLiteral is what makes bare nil type-check as any optional
type.
Sequence and Collection
Sequence requires only makeIterator() → some IteratorProtocol, which is enough to support for…in and
every lazy, one-pass algorithm (map, filter, reduce, …); Collection refines it with random-access
indices (startIndex, endIndex, subscript), letting a value be traversed more than once and indexed
directly. See Collections for the concrete Array, Set and
Dictionary types built on these protocols, and
Control Flow for for…in over any Sequence.
Optional and Result
Optional<Wrapped> and Result<Success, Failure> are ordinary enums in the standard library, not compiler
magic — Optional has cases none and some(Wrapped); Result has success(Success) and
failure(Failure). See Optionals for Optional in depth, and
Error Handling for Result alongside throws.
Ranges and Stride
let closed = 1...10 // ClosedRange<Int>
let halfOpen = 1..<10 // Range<Int>
let partial = 1... // PartialRangeFrom<Int>
for value in stride(from: 0, to: 10, by: 2) { // 0, 2, 4, 6, 8 -- `to` excludes the end
print(value)
}
for value in stride(from: 10, through: 0, by: -2) { // 10, 8, ..., 0 -- `through` includes the end
print(value)
}
Range/ClosedRange model a span between two bounds; stride(from:to:by:)/stride(from:through:by:) produce a
Sequence stepping by an arbitrary amount, which a plain range (whose implicit step is always 1) cannot
express. See Operators for the …/..< range operators
themselves.
print, readLine and Random Numbers
print("value:", 42, separator: " ", terminator: "\n") // configurable separator/terminator
let line = readLine() // String?, nil at end-of-input
let roll = Int.random(in: 1...6)
let coin = Bool.random()
let card = ["clubs", "diamonds", "hearts", "spades"].randomElement() // Element?, nil if empty
Int.random(in:), Double.random(in:), Bool.random() and Collection.randomElement()/shuffled() all draw
from the system’s default random source; a type conforming to RandomNumberGenerator can be passed explicitly
(Int.random(in: 1…6, using: &myGenerator)) for reproducible sequences in tests.
Codable, in Overview
Codable (Encodable & Decodable) lets a type convert to and from an external representation such as JSON,
with conformance synthesized automatically when every stored property is itself Codable. This page stops at
that overview — see Codable and Serialization
for CodingKeys, custom init(from:)/encode(to:), and JSONEncoder/JSONDecoder in depth.
|
|
Never
func fatalErrorExample() -> Never {
fatalError("unreachable")
}
func processOrCrash(_ value: Int?) -> Int {
guard let value else {
fatalError("value must not be nil") // return type Never unifies with Int here
}
return value
}
Never is an enum with no cases, so no value of type Never can ever exist; a function returning Never
therefore can never return normally — it must trap, loop forever, or throw. The type checker exploits this:
Never unifies with any other type, which is why a guard/switch branch calling a Never-returning function
type-checks against whatever the surrounding function actually returns.
See Also
-
Optionals —
Optionalin depth. -
Error Handling —
Resultandthrows. -
Collections —
Array,Set,Dictionarybuilt onSequence/Collection. -
Codable and Serialization —
Codablein depth. -
Protocols — protocols in general, including synthesized conformance.