Swift Structures
Value types for modeling data and behavior
🧱 What are Swift Structures?
Structures are value types that encapsulate data and functionality. They're copied when assigned or passed around, making them safe and predictable. Structs are Swift's preferred way to model simple data.
// Basic structure definition
struct Point {
var x: Double
var y: Double
func distance(to other: Point) -> Double {
let dx = x - other.x
let dy = y - other.y
return sqrt(dx * dx + dy * dy)
}
}
let point1 = Point(x: 0, y: 0)
let point2 = Point(x: 3, y: 4)
print(point1.distance(to: point2)) // Output: 5.0
Key Structure Features
Value Types
Structs are copied when assigned
var point1 = Point(x: 1, y: 2)
var point2 = point1
point2.x = 5
print(point1.x) // Still 1
Automatic Initializers
Free memberwise initializers
struct Person {
var name: String
var age: Int
}
let person = Person(name: "Alice", age: 30)
Mutating Methods
Methods that modify struct properties
struct Counter {
var count = 0
mutating func increment() {
count += 1
}
}
Computed Properties
Properties that calculate values
struct Circle {
var radius: Double
var area: Double {
return .pi * radius * radius
}
}
🔹 Basic Structure Example
Here's a simple structure representing a book:
struct Book {
var title: String
var author: String
var pages: Int
var isRead: Bool = false
var description: String {
return "\(title) by \(author) (\(pages) pages)"
}
mutating func markAsRead() {
isRead = true
print("Marked '\(title)' as read")
}
func recommendationLevel() -> String {
if pages < 200 {
return "Quick read"
} else if pages < 400 {
return "Standard read"
} else {
return "Long read"
}
}
}
var myBook = Book(title: "Swift Programming", author: "Apple", pages: 350)
print(myBook.description)
print("Recommendation: \(myBook.recommendationLevel())")
myBook.markAsRead()
Output:
Swift Programming by Apple (350 pages)
Recommendation: Standard read
Marked 'Swift Programming' as read
🔹 Mutating Methods
Use mutating methods to modify struct properties:
struct Temperature {
var celsius: Double
var fahrenheit: Double {
get {
return celsius * 9/5 + 32
}
set {
celsius = (newValue - 32) * 5/9
}
}
mutating func increaseByCelsius(_ amount: Double) {
celsius += amount
}
mutating func increaseByFahrenheit(_ amount: Double) {
fahrenheit += amount
}
}
var temp = Temperature(celsius: 20.0)
print("Initial: \(temp.celsius)°C, \(temp.fahrenheit)°F")
temp.increaseByCelsius(5.0)
print("After +5°C: \(temp.celsius)°C, \(temp.fahrenheit)°F")
temp.increaseByFahrenheit(10.0)
print("After +10°F: \(temp.celsius)°C, \(temp.fahrenheit)°F")
Output:
Initial: 20.0°C, 68.0°F
After +5°C: 25.0°C, 77.0°F
After +10°F: 30.56°C, 87.0°F
🔹 Custom Initializers
Create custom initializers for more control over struct creation:
struct Rectangle {
var width: Double
var height: Double
// Custom initializer
init(width: Double, height: Double) {
self.width = max(0, width) // Ensure positive values
self.height = max(0, height)
}
// Convenience initializer for squares
init(side: Double) {
self.init(width: side, height: side)
}
// Initializer with default values
init() {
self.init(width: 1.0, height: 1.0)
}
var area: Double {
return width * height
}
var isSquare: Bool {
return width == height
}
}
let rect1 = Rectangle(width: 5.0, height: 3.0)
let square = Rectangle(side: 4.0)
let defaultRect = Rectangle()
print("Rectangle area: \(rect1.area)")
print("Square area: \(square.area), is square: \(square.isSquare)")
print("Default area: \(defaultRect.area)")
Output:
Rectangle area: 15.0
Square area: 16.0, is square: true
Default area: 1.0
🔹 Value Semantics
Structures demonstrate value semantics - each instance is independent:
struct Player {
var name: String
var score: Int
mutating func addPoints(_ points: Int) {
score += points
print("\(name) scored \(points) points! Total: \(score)")
}
}
var player1 = Player(name: "Alice", score: 100)
var player2 = player1 // Creates a copy
player1.name = "Alice Smith"
player2.addPoints(50)
print("Player 1: \(player1.name), Score: \(player1.score)")
print("Player 2: \(player2.name), Score: \(player2.score)")
Output:
Alice scored 50 points! Total: 150
Player 1: Alice Smith, Score: 100
Player 2: Alice, Score: 150
🔹 When to Use Structures
Structures are ideal for many common programming tasks:
Perfect for Structures:
- Simple data models: Points, sizes, colors, coordinates
- Value semantics: When you want independent copies
- Mathematical objects: Vectors, matrices, complex numbers
- Configuration objects: Settings, preferences, options
- Small collections: Ranges, pairs, tuples
Consider Classes Instead When:
- You need inheritance
- You need reference semantics (shared instances)
- You need deinitializers
- You need identity checking (===)