Classes and Structs in Swift

In Swift, structs are value types ideal for defining simple data models like Pokémon, providing safety through data copying. Classes, as reference types, suit complex entities like Pokémon Trainers, facilitating shared data manipulation and inheritance for extended functionalities. Deciding between structs and classes depends on whether your data should be copied or shared, impacting your application's architecture and data integrity.

article

In Swift, classes and structs are fundamental building blocks of your code. They seem similar but serve different purposes in the architecture of an application. To make these concepts easier to grasp, let's dive into the world of Pokémon, using them as examples to understand when and why to use classes, structs, and what final class means.


What are Structs in Swift


Structs, short for structures, are types that encapsulate related properties and methods. Think of a struct as a simple container that holds information about something in an organized way. In the context of Pokémon, you might use a struct to represent a Pokémon with properties like name, type, and level.

        
    struct Pokemon {
        var name: String
        var type: String
        var level: Int
    }
        
    

Here, each Pokemon struct instance can hold data for a specific Pokémon. You can create a Pikachu like this:

    
 var pikachu = Pokemon(name: "Pikachu", type: "Electric", level: 5)
 

Why do we use Structs


Structs are value types, meaning when you assign them to a variable or pass them to a function, a copy is created. Use structs when you want to ensure that the data is copied rather than shared. Structs are best for representing simple data models without needing to inherit properties from another struct or class.


What are Classes in Swift


Classes are more complex than structs and allow for more flexibility. They are reference types, which means when you pass a class instance around in your code, you're sharing the same instance rather than a copy. Let's model a Trainer using a class:


        
class Trainer {
    var name: String
    var gym: String
    var pokemons: [Pokemon]
    
    init(name: String, gym: String, pokemons: [Pokemon]) {
        self.name = name
        self.gym = gym
        self.pokemons = pokemons
        }
}
     
    

Here, a Trainer has a name, is associated with a gym, and has a collection of Pokémon. Notice the init method; classes need initializers to set up their properties when creating an instance.


Why do we Use Classes?


Classes are used when you need more than one reference to the same instance or when you want to use inheritance to create a new class based on an existing one. Since classes are reference types, if you assign a class instance to a variable or pass it to a function, you're working with the same instance. This is useful for things that are meant to be unique or shared.

Classes vs. Structs: When to Use Each?


  • Use structs when you want to model simple data that is copied rather than shared. Structs come with a default initializer, making them easy to use for simple models. They are great for defining the model layer of your app, where immutable data is a priority.
  • Usere classes when you need to create complex data models that can be shared or modified by different parts of your app. Classes also support inheritance, making them suitable for situations where you need to create a hierarchy of types.

Practical Example: Pokémon in Action


Imagine you're building a Pokémon app. You might use a struct to represent each Pokémon because each Pokémon instance holds its unique set of properties (like name and level) that do not need to be shared or modified elsewhere.


    
    var charmander = Pokemon(name: "Charmander", type: "Fire", level: 8)
 

However, for a Trainer, which represents a more complex entity that interacts with various parts of your app and manages Pokémon (which can be added or removed from the trainer's collection), a class is more appropriate.


    
    let ash = Trainer(name: "Ash Ketchum", gym: "Pewter", pokemons: [pikachu, charmander])

 

Using classes and structs appropriately in Swift allows you to design your app's architecture clearly and efficiently. By leveraging the strengths of each, you can ensure that your data is handled in a way that makes sense for the functionality of your app, making your code cleaner, more efficient, and easier to maintain. Remember, the choice between classes and structs is not just about syntax, but about the semantics of what you're trying to model: shared versus copied, complex versus simple. As you grow more comfortable with Swift, these decisions will become second nature, helping you build robust and flexible apps.

instructor

Exodai INSTRUCTOR!

Johan t'Sas

Owner and Swift developer!