struct — what it is, key concepts and syntax in Swift

Author: IT Sectr Published: 2026-06-17 Reading time: 7 min

Struct is a value type in the Swift language, instances of which are copied when passed between parts of code. Unlike classes, structures do not support inheritance, but they implement protocols, contain properties and methods, and provide predictable memory management without ARC. According to the Swift Programming Language Guide, 2026, struct is a fundamental building block of Swift — even standard types Int, String, Array and Dictionary are implemented as structures. The language recommends structures as the preferred choice for data modeling.

Key Takeaways

  • Struct is a value type in Swift that is copied upon assignment and passed by value, not by reference.
  • Copy-on-Write is an optimization where actual data copying occurs only when the value is modified, not upon assignment.
  • Mutating is a keyword required for methods that modify the properties of a structure.
  • Protocols — structures can implement protocols and extensions, providing flexibility without inheritance.
  • Safety — the absence of reference cycles makes structures preferable for multithreaded code and data models.

What is struct in Swift?

Struct (structure) is a composite data type in Swift that groups related properties and methods into a single entity. Unlike classes, structures are value types: when passed to a function or assigned to a new variable, an independent copy of the structure is created, not a reference to the original object.

Swift uses structures for all primitive types: Int, Double, String, Bool, Array, Dictionary and Set. This means that even a basic Int behaves as a structure — a copy is created upon assignment. Developers can define their own structures with any set of properties and methods.

According to Swift Evolution (SE-0143), the decision to implement standard types as structures is driven by performance and predictability. Value types do not create reference cycles, do not require ARC reference counting, and guarantee that modifying a copy will not affect the original — this is critically important for data immutability in multithreaded scenarios.

Struct as a value type

Value type semantics is the key difference between struct and class. When you assign a structure to a new variable or pass it to a function, Swift creates an independent copy of all data. Any changes to the copy do not affect the original, eliminating the side effects typical of reference types.

swift
// Example of value type semantics
struct Point {
    var x: Double
    var y: Double
}

var p1 = Point(x: 10, y: 20)
var p2 = p1        // p2 is an independent copy of p1
p2.x = 99            // Only p2 changes
print(p1.x)         // 10 — p1 unchanged
print(p2.x)         // 99

Copy-on-Write optimization

Swift uses Copy-on-Write (COW) to optimize copying. If multiple variables reference the same structure but none of them modifies the data, no actual copying occurs. Swift shares memory between variables until the first mutation — then a real copy is created. This prevents excessive allocate operations and speeds up work with collections.

Mutability and mutating methods

By default, structure methods cannot modify the structure’s properties — Swift requires the explicit mutating keyword for methods that make changes. This restriction protects against accidental mutation and makes the code predictable: if a method is not marked as mutating, you are guaranteed not to change the structure.

Mutating in action

When you add the mutating keyword before a method, Swift gains the ability to write new values to the structure’s properties. In fact, the method can even completely replace the structure instance with a new one via self =. This mechanism is used, for example, in Option and Result types.

swift
// Struct with mutating method
struct Counter {
    private var value: Int = 0

    // Mutating method — can modify properties
    mutating func increment() {
        value += 1
    }

    // Mutating method can replace self entirely
    mutating func reset() {
        self = Counter()
    }

    // Non-mutating method — read only
    func currentValue() -> Int {
        return value
    }
}

var counter = Counter()
counter.increment()
print(counter.currentValue())  // 1
counter.reset()
print(counter.currentValue())  // 0

Rules for mutating: the structure must be declared with var, not let — a constant structure cannot call a mutating method. The compiler checks this at build time: attempting to call a mutating method on a let-constant will result in a compilation error.

Struct vs Class: comparison

The choice between struct and class is one of the fundamental decisions in Swift. Both types can contain properties, methods, initializers and implement protocols, but they have fundamental differences in memory semantics, inheritance and lifecycle management.

Featurestructclass
TypeValue type (copied)Reference type (reference)
InheritanceNot supportedSupported
ARC / reference countingNot requiredARC required
DeinitializationNot supportedSupports deinit
Property mutation in constantsOnly via varPossible via let (reference is constant)
Type castingNot supportedSupported
Storage in collectionsStored directly (value)Stored as reference (pointer)

Structures are preferred when data does not require inheritance, should not have shared identity (e.g., coordinates, sizes, configuration) and are passed between modules. Classes are chosen for UI components (UIView, UIViewController), singletons and objects with shared identity.

When to choose struct

Apple recommends using struct as the default type for data modeling in Swift. Structures are suitable for most scenarios due to predictable copy semantics and no overhead from reference counting. Let’s look at typical cases where struct is the optimal choice.

Data models without inheritance

If an entity contains data without needing inheritance (Product, User, Order, Point), use struct. The compiler automatically generates a memberwise initializer — you don’t need to write init manually. Equatable and Hashable are also automatically implemented for structures whose properties all conform to these protocols.

Immutable data

For configurations, settings and flags that don’t change after creation, struct is preferable to class. A constant (let) structure guarantees the immutability of all nested fields — in a class this only applies to the reference, not to the object’s contents.

Multithreaded code

Structures are safe in multithreaded environments due to value semantics. Each thread gets an independent copy of the data and does not affect other threads. Data races between threads are impossible for value types, making struct the preferred choice for models in SwiftUI (ObservableObject requires class, but @State uses struct).

swift
// Example of struct usage for data model
struct User: Codable, Identifiable {
    let id: UUID
    var name: String
    var email: String
    var isPremium: Bool

    // Computed property — non-mutating
    var displayName: String {
        isPremium ? "\(name) ⭐️" : name
    }
}

// Automatic memberwise initializer
let user = User(
    id: UUID(),
    name: "Alice",
    email: "alice@example.com",
    isPremium: true
)

// Copying is safe for multi-threading
var userCopy = user
userCopy.isPremium = false
// user.isPremium remains true

Use class when you need inheritance (UIKit/AppKit components), shared identity (delegate, observer) or controlled object lifecycle (deinit). For everything else — use struct.

Frequently Asked Questions

What is struct in Swift?

Struct in Swift is a value type that is copied when passed between parts of code. Structures can contain properties, methods, initializers and implement protocols. Basic Swift types (Int, String, Array) are implemented as structures.

What is the difference between struct and class in Swift?

Struct is a value type (copied on assignment), does not support inheritance and does not require ARC. Class is a reference type (passed by reference), supports inheritance, deinitialization and reference counting. Developers recommend struct as the default type.

What is mutating in struct Swift?

Mutating is a keyword that indicates a structure method can modify its properties. Without mutating, the compiler forbids field modification. Mutating methods can only be called on variables declared with var, not let.

What is Copy-on-Write in Swift?

Copy-on-Write (COW) is a Swift optimization for structures where actual data copying is deferred until the first mutation. As long as all variables only read the structure, they share a single memory area. This improves performance when working with large collections.

When to use struct and when to use class in Swift?

Use struct for data models without inheritance, configurations, DTOs and multithreaded scenarios. Use class for UIKit/AppKit UI components, singletons, entities with shared identity (delegate, observer) and objects requiring deinitialization.

Summary

  • Struct is a value type in Swift that is copied upon assignment, providing predictable behavior without side effects between copies.
  • Copy-on-Write optimizes structure performance — real copying occurs only at the first mutation, not at every assignment.
  • Standard Swift types — Int, String, Array, Dictionary — are implemented as structures, guaranteeing value semantics for all basic operations.
  • Mutating is a mandatory keyword for methods that modify structure properties; it can only be called on var instances.
  • Structures do not support inheritance but implement protocols and can use extensions to add functionality.
  • Equatable and Hashable are automatically implemented for structures whose properties all conform to these protocols — simplifying comparison and use in collections.
  • Apple recommends struct as the default type — use class only when inheritance, shared identity or controlled object lifecycle is required.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also