W Swift od samego początku położono nacisk na typy wartości — struktury (struct) jako podstawowe narzędzie modelowania danych. W przeciwieństwie do Objective-C, gdzie wszystko było obiektami (klasami), Swift zachęca do używania struktur do prostych modeli, danych i małych obiektów biznesowych.
Wielu programistów, szczególnie tych z doświadczeniem w innych językach obiektowych, błędnie używa klas do wszystkiego. Prowadzi to do problemów z pamięcią (cykle referencyjne), niespodziewanych zmian podczas przekazywania obiektów i trudności z bezpieczeństwem wątków, ponieważ klasy to typy referencyjne.
Struktury w Swift to typy wartości, są kopiowane przy przypisywaniu i przekazywaniu do funkcji, w przeciwieństwie do klas (typy referencyjne), które przekazują referencję. To sprawia, że struktury są preferowane dla modeli bez złożonej logiki cyklu życia i dziedziczenia.
Przykład kodu:
struct Point { var x: Int var y: Int } var p1 = Point(x: 10, y: 20) var p2 = p1 p2.x = 30 // p1.x pozostaje równe 10
Kluczowe cechy:
Czy struktura może mieć dziedzica (subclass)?
Nie, struktury w Swift nie wspierają dziedziczenia. Wszystkie rozszerzenia zachowania są możliwe tylko przez protokoły i rozszerzenia.
Czy to oznacza, że struktura zawsze jest kopiowana podczas przekazywania do funkcji?
W praktyce, Swift używa optymalizacji Copy-On-Write. Jeśli nie zmieniamy struktury, nie jest ona kopiowana, a kopia powstaje tylko przy zmianie. Dotyczy to standardowych kolekcji i złożonych struktur.
var arr1 = [1, 2, 3] var arr2 = arr1 arr2.append(4) // Tylko tutaj następuje kopiowanie
W jakich przypadkach nie można używać struktury?
Używano klas do przechowywania jednorodnych danych (na przykład do punktów na mapie), co skutkowało utratą wydajności z powodu częstego dostępu do pamięci, trudnym zarządzaniem pamięcią i błędami z pomieszanymi referencjami.
Zalety:
Wady:
Użycie struktur do modeli danych, które są bezpiecznie kopiowane, nie prowadzą do wycieków i nie mają zbędnej złożoności.
Zalety:
Wady: