tezvyn:

Swift Structs vs. Classes: Value vs. Reference Types

AI-drafted, machine-checkedSource: docs.swift.orgintermediate

In Swift, a struct is a copied value (like a new document), while a class is a shared reference (like a link to one document). Use structs for simple data like coordinates; use classes for shared state like a user session.

WHY IT EXISTS Swift provides two ways to define custom data types to solve two different problems. One tool is for creating simple, self-contained values that are safe to pass around (structs). The other is for creating complex objects that have a distinct identity and can be shared and modified from multiple places (classes). This distinction gives developers precise control over how data is stored and manipulated, which directly impacts performance and code correctness.

THE MENTAL MODEL A struct is a value type. Think of it as a blueprint for a unique, independent object. When you assign or pass a struct, you create a complete copy. Changing the copy leaves the original untouched. A class is a reference type. Think of it as a blueprint for an object that lives at a specific address in memory. When you assign or pass a class instance, you're just copying the address, not the object itself. All copies of the address point to the same, single object.

HOW IT WORKS Structs are value types, typically stored on the stack, which is fast for allocation and deallocation. Because they are copied on assignment, you can reason about them locally without worrying about remote changes. Many of Swift's fundamental types, like String, Array, and Dictionary, are implemented as structs with copy-on-write optimizations to make copying efficient.

Classes are reference types, stored on the heap. Instances are managed by Automatic Reference Counting (ARC), which tracks how many references point to an object and deallocates it when the count hits zero. Classes support inheritance, allowing one class to inherit characteristics from another. They also support deinitializers to clean up resources before an instance is deallocated.

WHEN TO USE IT Use a struct by default. They are safer because they prevent shared mutable state, a common source of bugs. They are perfect for modeling data that doesn't have a unique identity, like a Point on a coordinate plane, a Size, or a Color. If you can say that two instances with the same internal values are interchangeable, you want a struct.

Use a class when you need a single, shared identity. This is for objects that represent a specific entity, like a UserManager, a NetworkService, or a ViewController. If multiple parts of your app need to interact with the exact same instance, you need a class. Classes are also required for interoperability with Objective-C frameworks.

WHEN NOT TO USE IT Avoid using a class for simple data aggregates. If you use a class for something like a Point, you risk one part of your code changing the point's coordinates and unknowingly affecting a completely different part of the app that holds a reference to that same point. This is called "spooky action at a distance."

ONE CANONICAL EXAMPLE Consider a struct Point { var x = 0, y = 0 }. If you create var p1 = Point() and then var p2 = p1, they are two separate instances. If you then write p2.x = 100, the value of p1.x remains 0. Now consider a class Window { var title = "" }. If you create var w1 = Window() and then var w2 = w1, both w1 and w2 refer to the same object. If you write w2.title = "Main", the value of w1.title also becomes "Main".

Read the original → docs.swift.org

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.