Victor Campos
Swift for Beginners: Structures vs Classes | Background Image

Swift for Beginners: Structures vs Classes

Photo by J Venerosy on Unsplash

As a beginner in Swift, structures and classes might be a little hard to understand because they are very similar to one another and they can do pretty much the same thing. In this article I'd like to give you a brief explanation of what I've learned are the main differences between classes and structures and how to choose which one to use.

Overview

In Swift, classes and structs are like a blueprint for creating objects or types. As I've said, they are very similar, and both of them can define properties to store value and methods to provide functionality.

They have a lot more in common, but let's stick with the basics here and put this into code by creating a developer type.

class Developer {
	var cProperty: String
 
	func cMethod() {}
}
 
struct Developer {
	var sProperty: String
 
	func sMethod() {}
}

Creating new instances

One of the things that differentiates structures from classes is that, unlike classes, we don't have to write the initializer for the structure properties. We could just create a new instance passing its initial values.

struct Developer {
	var sProperty: String
 
	func sMethod() {}
}
 
var newStruct = Developer(sProperty: "value")

For classes, we have to write the initializer.

class Developer {
	var cProperty: String
 
	init(cProperty: String) {
		self.cProperty = cProperty
	}
 
	func sMethod() {}
}
 
var newClass = Developer(cProperty: "value")

That's an easy difference to understand and you don't have to worry about it too much, Xcode will always give you an error whenever you forget to write the initializer for your classes.

Let's get on with more advanced concepts and differences between structs and classes.

Key Differences

Now, we know that both classes and structs are used to create types and objects. The next question you probably have in mind is when should we use one or the other. To answer this question we need to understand what are the key differences between them.

Reference vs Value types

The main difference between a class and a structure is that a struct is a value type, and that means that it's copied whenever it's used. While the class is a reference type. Let's break this down.

Imagine we're working on a presentation together and we've got a template that we're using to create this presentation. We'll represent this template in our code using a struct.

struct PresentationTemplate {
	var numberOfSlides: Int
}

Then, I give you one copy of the template and I have one copy as well.

var template = PresentationTemplate(numberOfSlides: 4)
 
var myTemplate = template
var yourTemplate = template

Because we're using a struct, no matter what change you make on your template, it won't affect the copy I have.

yourTemplate.numberOfSlides += 2
 
print(yourTemplate.numberOfSlides) // 6
print(myTemplate.numberOfSlides) // 4

Now, if we were working with classes, because classes are a reference type, every single thing that you do on your template will affect mine too, they are the same one.

class PresentationTemplate {
    var numberOfSlides: Int
 
    init(numberOfSlides: Int) {
        self.numberOfSlides = numberOfSlides
    }
}
 
var template = PresentationTemplate(numberOfSlides: 4)
 
var myTemplate = template
var yourTemplate = template
 
yourTemplate.numberOfSlides += 2
 
print(yourTemplate.numberOfSlides) // 6
print(myTemplate.numberOfSlides) // 6

Inheritance

Inheritance is a fundamental behavior that differentiates classes from structures. Basically, a class can inherit methods and properties from another class.

Let's create a class called Developer and add some properties and methods for it.

class Developer {
	var skills = ["Write code"]
 
	func introduce() {
		print("I'm a software engineer and I can write code.")
	}
}

Then, we will create a class called TechLead. This class will have everything that our class Developer has by inheriting from it, and we can check this by accessing a method or property from the Developer class.

class TechLead: Developer {}
 
TechLead().introduce()
// "I'm a software engineer and I can write code."

Not only a subclass can inherit from the superclass, but also provide its own custom implementation for the inherited methods and properties. This is known as overriding.

class Developer {
	var skills = ["Write code"]
 
	func introduce() {
		print("I'm a software engineer and I can write code.")
	}
}
 
class TechLead: Developer {
	override func introduce() {
		super.introduce()
		print("Also, I lead a team of developers.")
	}
}
 
Developer().introduce()
// "I'm a software engineer and I can write code."
 
TechLead().introduce()
// "I'm a software engineer and I can write code."
// "Also, I lead a team of developers."

In this case, we've used the existing superclass implementation as part of our override. But we could've totally changed the behavior of the method by removing super.introduce() from our function.

class TechLead: Developer {
	override func introduce() {
		print("I'm a Tech Leader and I manage a team of developers")
	}
}
 
Developer().introduce()
// "I'm a software engineer and I can write code."
 
TechLead().introduce()
// "I'm a Tech Leader and I manage a team of developers"

Which one to use

If you check Swift doc, Apple recommends using structures over classes. On top of the fact that structs include many features limited to classes in other languages, they're also simpler to use, faster, and result in less memory leaks.

So, whenever you have doubt about which one to use, go with struct and consider switching to a class if you realize that you need features only classes can provide, like inheritance.

Conclusion

Michael Jordan onde said: "Get the fundamentals down and the level of everything you do will rise." That's the purpose of this article: to help you work the fundamentals and start building the foundation for coding great applications.

But this is far away from being enough. As seen in the last section, there's a lot more for you (and for me as well) to explore and understand about structures and classes in Swift. Why do structs result in fewer memory leaks? Why are they faster?

These are questions that, by design, weren't covered in here but they're great next steps for us to explore. So I'll do my part from here and I truly hope that you'll do yours from there. Great work, and see you next time! 🙋🏻‍♂️