Struct to typ-wartość (value type) w języku Swift, którego instancje są kopiowane przy przekazywaniu między fragmentami kodu. W przeciwieństwie do klas, struktury nie obsługują dziedziczenia, ale implementują protokoły, zawierają właściwości i metody oraz zapewniają przewidywalne zarządzanie pamięcią bez ARC. Według Swift Programming Language Guide, 2026, struct jest podstawowym blokiem konstrukcyjnym Swift — nawet standardowe typy Int, String, Array i Dictionary są zaimplementowane jako struktury. Język zaleca struktury jako priorytetowy wybór do modelowania danych.
Najważniejsze
Struct (struktura) — to złożony typ danych w Swift, który grupuje powiązane właściwości i metody w jedną encję. W przeciwieństwie do klas, struktury są value types: przy przekazaniu do funkcji lub przypisaniu do nowej zmiennej tworzona jest niezależna kopia struktury, a nie referencja do oryginalnego obiektu.
Swift używa struktur dla wszystkich typów prymitywnych: Int, Double, String, Bool, Array, Dictionary i Set. Oznacza to, że nawet podstawowa liczba Int zachowuje się jak struktura — przy przypisaniu tworzona jest kopia. Deweloper może zdefiniować własną strukturę z dowolnym zestawem właściwości i metod.
Według Swift Evolution (SE-0143), decyzja o implementacji standardowych typów jako struktur wynika z wydajności i przewidywalności. Value types nie tworzą cykli referencyjnych, nie wymagają zliczania referencji ARC i gwarantują, że zmiana kopii nie wpłynie na oryginał — jest to kluczowe dla niemutowalności danych w scenariuszach wielowątkowych.
Value type semantics — kluczowa różnica między struct a class. Gdy przypisujesz strukturę do nowej zmiennej lub przekazujesz ją do funkcji, Swift tworzy niezależną kopię wszystkich danych. Wszelkie zmiany w kopii nie wpływają na oryginał, co eliminuje efekty uboczne charakterystyczne dla typów referencyjnych.
// Przykład semantyki value type
struct Point {
var x: Double
var y: Double
}
var p1 = Point(x: 10, y: 20)
var p2 = p1 // p2 jest niezależną kopią p1
p2.x = 99 // Zmienia się tylko p2
print(p1.x) // 10 — p1 bez zmian
print(p2.x) // 99
Swift używa Copy-on-Write (COW) do optymalizacji kopiowania. Jeśli kilka zmiennych odwołuje się do jednej struktury, ale żadna z nich nie modyfikuje danych, faktyczne kopiowanie nie następuje. Swift współdzieli pamięć między zmiennymi do pierwszej mutacji — wtedy tworzona jest prawdziwa kopia. Zapobiega to nadmiernym operacjom alokacji i przyspiesza pracę z kolekcjami.
Domyślnie metody struktury nie mogą modyfikować jej właściwości — Swift wymaga jawnego wskazania mutating dla metod, które wprowadzają zmiany. To ograniczenie chroni przed przypadkową mutacją i czyni kod przewidywalnym: jeśli metoda nie jest oznaczona mutating, masz gwarancję, że nie zmienisz struktury.
Gdy dodajesz słowo kluczowe mutating przed metodą, Swift zyskuje możliwość zapisania nowych wartości we właściwościach struktury. W rzeczywistości metoda może nawet całkowicie zastąpić instancję struktury nową poprzez self = . Ten mechanizm jest używany na przykład w typach Option i Result.
// Struct z metodą mutating
struct Counter {
private var value: Int = 0
// Metoda mutating — może modyfikować właściwości
mutating func increment() {
value += 1
}
// Metoda mutating może całkowicie zastąpić self
mutating func reset() {
self = Counter()
}
// Metoda non-mutating — tylko do odczytu
func currentValue() -> Int {
return value
}
}
var counter = Counter()
counter.increment()
print(counter.currentValue()) // 1
counter.reset()
print(counter.currentValue()) // 0
Zasady dla mutating: struktura musi być zadeklarowana przez var, a nie let — dla stałej struktury nie można wywołać metody mutating. Kompilator sprawdza to na etapie budowania: próba wywołania metody mutating na stałej let spowoduje błąd kompilacji.
Wybór między struct a class — jedno z fundamentalnych rozwiązań w Swift. Oba typy mogą zawierać właściwości, metody, inicjalizatory i implementować protokoły, ale mają zasadnicze różnice w semantyce pamięci, dziedziczeniu i zarządzaniu cyklem życia.
| Cecha | struct | class |
|---|---|---|
| Typ | Value type (kopiowany) | Reference type (referencja) |
| Dziedziczenie | Nie obsługuje | Obsługuje |
| ARC / zliczanie referencji | Niewymagane | Wymaga ARC |
| Deinicjalizacja | Nie obsługuje | Obsługuje deinit |
| Modyfikacja właściwości w stałej | Tylko przez var | Można przez let (referencja stała) |
| Rzutowanie typów | Nie obsługuje | Obsługuje |
| Przechowywanie w kolekcjach | Przechowywane bezpośrednio (wartość) | Przechowywane jako referencja (wskaźnik) |
Struktury są preferowane, gdy dane nie wymagają dziedziczenia, nie powinny mieć wspólnej tożsamości (np. współrzędne, wymiary, konfiguracja) i są przekazywane między modułami. Klasy są wybierane dla komponentów UI (UIView, UIViewController), singleton i obiektów ze wspólną tożsamością.
Apple zaleca używanie struct jako typu domyślnego do modelowania danych w Swift. Struktury nadają się do większości scenariuszy dzięki przewidywalnej semantyce kopiowania i braku narzutów na zliczanie referencji. Rozważmy typowe przypadki, gdy struct jest optymalnym wyborem.
Jeśli encja zawiera dane bez potrzeby dziedziczenia (Product, User, Order, Point), użyj struct. Kompilator automatycznie generuje memberwise initializer — nie musisz pisać init ręcznie. Equatable i Hashable również są implementowane automatycznie dla struktur, których wszystkie właściwości spełniają te protokoły.
Dla konfiguracji, ustawień i flag, które nie zmieniają się po utworzeniu, struct jest preferowany nad class. Stała (let) struktura gwarantuje niemutowalność wszystkich zagnieżdżonych pól — w class dotyczy to tylko referencji, a nie zawartości obiektu.
Struktury są bezpieczne w środowisku wielowątkowym ze względu na value semantics. Każdy wątek otrzymuje niezależną kopię danych i nie wpływa na inne wątki. Wyścigi danych między wątkami są niemożliwe dla value types, co czyni struct preferowanym wyborem dla modeli w SwiftUI (ObservableObject wymaga class, ale @State używa struct).
// Przykład użycia struct dla modelu danych
struct User: Codable, Identifiable {
let id: UUID
var name: String
var email: String
var isPremium: Bool
// Właściwość computed — non-mutating
var displayName: String {
isPremium ? "\(name) ⭐️" : name
}
}
// Automatyczny inicjalizator memberwise
let user = User(
id: UUID(),
name: "Alice",
email: "alice@example.com",
isPremium: true
)
// Kopiowanie jest bezpieczne dla wielowątkowości
var userCopy = user
userCopy.isPremium = false
// user.isPremium pozostaje true
Używaj class, gdy potrzebujesz dziedziczenia (komponenty UIKit/AppKit), wspólnej tożsamości (delegate, observer) lub kontrolowanego czasu życia obiektów (deinit). Do wszystkiego innego — struct.
Często zadawane pytania
Struct w Swift — to typ-wartość (value type), który jest kopiowany przy przekazywaniu między fragmentami kodu. Struktury mogą zawierać właściwości, metody, inicjalizatory i implementować protokoły. Podstawowe typy Swift (Int, String, Array) są zaimplementowane jako struktury.
Struct — value type (kopiowany przy przypisaniu), nie obsługuje dziedziczenia i nie wymaga ARC. Class — reference type (przekazywany przez referencję), obsługuje dziedziczenie, deinicjalizację i zliczanie referencji. Deweloperzy zalecają struct jako typ domyślny.
Mutating — słowo kluczowe, które wskazuje, że metoda struktury może modyfikować jej właściwości. Bez mutating kompilator zabrania modyfikacji pól. Metody mutating można wywoływać tylko na zmiennych zadeklarowanych przez var, a nie let.
Copy-on-Write (COW) — optymalizacja Swift dla struktur, w której faktyczne kopiowanie danych jest odkładane do momentu pierwszej mutacji. Dopóki wszystkie zmienne tylko odczytują strukturę, współdzielą jeden obszar pamięci. Zwiększa to wydajność przy pracy z dużymi kolekcjami.
Używaj struct dla modeli danych bez dziedziczenia, konfiguracji, DTO i scenariuszy wielowątkowych. Używaj class dla komponentów UI UIKit/AppKit, singleton, encji ze wspólną tożsamością (delegate, observer) i obiektów wymagających deinicjalizacji.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również