Arvindh Sukumar5 days ago2 min read
Advantages & Disadvantages of Structs in Swift
When designing the models and data structure for your app, you would probably be deciding between Structs and Classes.
If you’re coming from a different programming language, it’s easy to settle into a pattern of using classes throughout your app.
However, structs in Swift are highly significant — they have been given tremendous importance throughout the Swift Standard Library itself. You too, should keep them in mind for your own apps. The following set of pros and cons should help you make a decision in this regard.
Advantages:
- Structs are marginally faster at runtime than classes, due to optimisations done by the compiler.
- You can enforce full immutability. If you declare a struct instance as let, you will not be able to change its properties. Whereas, with classes, immutability is only with respect to the reference held by the constant — you’ll still be able to change its properties.
- Since structs are value types, each instance is a unique copy of data. Because of this, when using structs in a multi-threaded environment, each thread could have its own copy of the data, and chances are low of one thread changing data out under you in a different thread. Of course, if your instance of the struct is mutable, or if you mix reference types in your struct (see below), the chances of this happening are higher — but if you’re using a class, even the little safety you’d get is lost.
Disadvantages
- Structs do not support inheritance. Depending on how you look at it, this may not be a bad thing, but this is certainly something to keep in mind while designing your models.
- They cannot conform to a class protocol (duh), such as NSObjectProtocol. This seems like an obvious thing to say, but you may never know at what point you need to start complying to a protocol — and a lot of Foundation protocols (for example) have been defined as class protocols.
- You lose identity (===) comparison. Identity comparison is useful in cases like event handling, when you want to check which object emitted the event. With classes, you can do, for example if (sender === instance).
- Structs are cool when used as pure value types, i.e a single struct made up of other value types — structs or enums. But when you bring reference semantics into the equation, things can get messy. The thing is, while a struct is copied by value on assignment, any property that is a reference type is copied by — you guessed it — reference. Even if it is marked as let, if the reference type is mutated elsewhere, the struct is also affected. For example:
struct Person {var name: String
var job: Job
}
class Job {var title: String!
}
var job = Job()
job.title = “Accountant”
let person1 = Person(name: “John”, job: job)
let person2 = person1 // Hey, let's clone John!
person1.job.title = “Software Engineer”
print(person1.job.title) // Software Engineer
print(person2.job.title) // Software Engineer (!)
These are just a few things you can keep in mind. Anything you think I’ve missed out? Let me know!