Structs & Classes
Structs and classes are both building blocks in Swift used to create custom data types. You use them to group related variables and functions together.
Commonalities
Both can:
- Define properties to store values.
- Define methods to provide functionality.
- Define initializers to set up their initial state.
- Be extended to expand their functionality (Explained later).
Properties
Properties are simply variables or constants associated with a particular class or struct. Just like global variables, they can be Stored or Computed.
swift
struct Circle {
var radius: Double // Stored Property
var area: Double { // Computed Property
3.14159 * radius * radius // Implicit return
}
}The Key Differences: Struct vs Class
| Feature | Structs | Classes |
|---|---|---|
| Type Category | Value Type: Stored directly. | Reference Type: Stored as a pointer. |
| Storage | Copied: Each variable gets its own unique copy of the data. | Shared: Multiple variables point to the exact same instance. |
| Inheritance | ❌ No inheritance support. | ✅ Can inherit from other classes. |
Initializers (init) | 🪄 Gets a Memberwise Initializer automatically. | ✍️ You must write your own initializers. |
| Mutability | 🔒 If the struct is let, you cannot change its properties. | 🔓 If the class is let, you can still change its var properties. |
Cleanup (deinit) | ❌ No deinitializers. | ✅ Supports deinit for cleanup right before it is destroyed. |
Identity Check (===) | ❌ Not available (value types have no identity). | ✅ Classes Only: Use === to check if same instance. |
| Memory | ⚡ Fast: Stored on the Stack. | 🐢 Slower: Stored on the Heap. |
| Use Case | Default Choice. Use for 90% of things (models, state). | Use for complex objects with shared state or inheritance. |
NOTE
Memberwise Initializers: A "magic" feature where the Swift compiler automatically generates an initializer for structs based on their properties. Classes do not get this.
Struct Example (Value Type)
swift
struct Resolution {
var width = 0
var height = 0
}
let hd = Resolution(width: 1920, height: 1080) // Memberwise Initializer: no manual 'init' needed
var cinema = hd // 📦 A COPY is created here
cinema.width = 2048 // Only 'cinema' changes; 'hd' remains 1920Class Example (Reference Type)
swift
class VideoMode {
var resolution: Resolution
var frameRate: Double
// Classes need manual initializers
init(resolution: Resolution, frameRate: Double) {
self.resolution = resolution
self.frameRate = frameRate
}
}
let tenEighty = VideoMode(resolution: hd, frameRate: 60.0)
let alsoTenEighty = tenEighty // 🔗 Both point to the SAME instance
alsoTenEighty.frameRate = 30.0 // Changing 'alsoTenEighty' also changes 'tenEighty'When to use which?
- Use Structs by default. They are safer and faster.
- Use Classes when you need inheritance or shared identity (reference types).
