Lesson 59Structs
Struct Best Practices
Writing Better Structs
Follow these best practices to write clean, maintainable, and efficient Swift structs that your future self will thank you for!
Top 10 Best Practices
1. Use Structs by Default
Prefer structs over classes
2. Keep Structs Focused
Single responsibility
3. Meaningful Names
Clear, descriptive naming
4. Default Values
Easier initialization
5. Computed Properties
For derived values
6. Mark Mutating
Clear intent
7. Access Control
Hide implementation
8. Use Protocols
Add functionality
9. Use Extensions
Organize code
10. Document Code
Help future you
When to Use Class Instead
- You need identity (reference semantics)
- You need inheritance
- You need deinitializers
- Shared mutable state is required
Access Control Levels
private - Only within the type
fileprivate - Only within the file
internal - Within the module (default)
public - Anywhere, but can't subclass
open - Anywhere, can subclass
best_practices.swift
// STRUCT BEST PRACTICES
// Guidelines for writing clean, efficient structs
// ===== 1. USE STRUCTS BY DEFAULT =====
// Prefer structs over classes when possible
// GOOD: Simple data container
struct UserProfile {
var name: String
var email: String
var age: Int
}
// ===== 2. KEEP STRUCTS SMALL & FOCUSED =====
// Single Responsibility Principle
// BAD: Too many responsibilities
struct BadUser {
var name: String
var email: String
func sendEmail() { }
func validatePassword() { }
func saveToDatabase() { }
}
// GOOD: Separate concerns
struct User {
var name: String
var email: String
}
struct EmailService {
func send(to user: User, message: String) { }
}
// ===== 3. USE MEANINGFUL NAMES =====
// Clear, descriptive property names
// BAD
struct P {
var x: Double
var y: Double
}
// GOOD
struct Coordinate {
var latitude: Double
var longitude: Double
}
// ===== 4. PROVIDE DEFAULT VALUES =====
// Make structs easier to initialize
struct Settings {
var theme: String = "light"
var fontSize: Int = 14
var notificationsEnabled: Bool = true
}
let defaultSettings = Settings()
let customSettings = Settings(theme: "dark")
// ===== 5. USE COMPUTED PROPERTIES WISELY =====
// For derived values, not stored data
struct Rectangle {
var width: Double
var height: Double
// GOOD: Derived from stored properties
var area: Double {
return width * height
}
var perimeter: Double {
return 2 * (width + height)
}
var isSquare: Bool {
return width == height
}
}
// ===== 6. MARK MUTATING METHODS EXPLICITLY =====
// Clear intent about what modifies state
struct Counter {
private(set) var value: Int = 0
mutating func increment() {
value += 1
}
mutating func reset() {
value = 0
}
// Non-mutating returns new instance
func adding(_ amount: Int) -> Counter {
return Counter(value: value + amount)
}
}
// ===== 7. USE ACCESS CONTROL =====
// Hide implementation details
struct BankAccount {
private(set) var balance: Double = 0
mutating func deposit(_ amount: Double) {
guard amount > 0 else { return }
balance += amount
}
mutating func withdraw(_ amount: Double) -> Bool {
guard amount > 0 && balance >= amount else {
return false
}
balance -= amount
return true
}
}
// ===== 8. CONFORM TO PROTOCOLS =====
// Add functionality through protocols
struct Task: Identifiable, Equatable, Codable {
let id: UUID
var title: String
var isCompleted: Bool
init(title: String) {
self.id = UUID()
self.title = title
self.isCompleted = false
}
}
// ===== 9. USE EXTENSIONS FOR ORGANIZATION =====
// Group related functionality
struct Product {
var name: String
var price: Double
}
extension Product: CustomStringConvertible {
var description: String {
return "\(name): $\(price)"
}
}
extension Product {
func withDiscount(_ percent: Double) -> Product {
let newPrice = price * (1 - percent / 100)
return Product(name: name, price: newPrice)
}
}
// ===== 10. DOCUMENT YOUR CODE =====
/// A struct representing a geographic location
struct Location {
/// Latitude in degrees (-90 to 90)
var latitude: Double
/// Longitude in degrees (-180 to 180)
var longitude: Double
/// Calculates distance to another location in kilometers
func distance(to other: Location) -> Double {
// Haversine formula implementation
return 0.0 // Simplified
}
}Try It Yourself!
Review a struct you've written and apply at least 3 best practices from this lesson to improve it!