(Swift) Classes and Structs

Kenta Kodashima
5 min readOct 3, 2018

--

Swift has two similar structures that are called Class and Struct. Even though those two look like they have the same structure, there’s a big difference under the hood. In this article, I will address the differences between those two.

1. Reference Type vs Value Type

First of all, their way of managing instances is different. While classes are reference types, structures are value types. Let’s take a look at the example below.

struct PersonStruct {
var firstName: String
var lastName: String
}
class PersonClass {
var firstName: String
var lastName: String
init(firstName: String, lastName: String) {
self.firstName = firstName
self.lastName = lastName
}
}
// Initialize a person class and assign it to another variable
let person1 = PersonClass(firstName: "Kenta", lastName: "Kodashima")
let person2 = person1
person2.firstName = "Kevin"
person1 // print "Kevin"
person2 // print "Kevin"
// Initialize a person struct and assign it to another variable
var person3 = PersonStruct(firstName: "Kenta", lastName: "Kodashima")
var person4 = person3
person4.firstName = "Kevin"
person3.firstName // print "Kenta"
person4.firstName // print "Kevin"

In the example above, there is a simple struct called PersonStruct and a class called PersonClass. After the declarations, PersonClass is initialized as person1 and PersonStruct is initialized as person3.

In order to see the difference between the class and the struct, assign each constant or variable to another constant or variable just like in the example. Then change the firstName property of person2 and person4, and you can see the difference. While person1 and person2 print exactly the same value, person3 prints the original value and person4 prints the modified value.

When PersonClass is initialized for person1, what is passed into is the reference to the PersonClass object. Therefore, person1 and person2 are pointing at exactly the same object in the memory.

On the other hand, when PersonStruct is initialized, the actual object is passed into person3 as its value. Thus, person3 and person4 have their own separated objects in the memory.

Note: When you work with the struct, defining init() is not necessary. If you don’t define your own custom init(), Swift automatically makes default init() with all the properties inside of the struct.

2. Mutable vs Immutable

Some of you might have noticed that person1 and person2 from the previous example are declared as constants, and person3 and person4 are declared as variables. Why, you ask?

For value types in Swift, storing it into let constant means the instance must remain constant. No properties of the instance cannot be changed, regardless whether the properties are declared with let or var .

Since struct itself is a value type, no properties of the instance cannot be changed if you store it into a let constant.

Additionally, the properties of a value type cannot be modified from within its instance methods by default. Let’s see what it means by adding a function into the struct in the example.

struct PersonStruct {
var firstName: String
var lastName: String

mutating func uppercasedName() {
firstName = firstName.uppercased()
lastName = lastName.uppercased()
}
}

The uppercasedName() function is a simple function which modifies struct’s properties. Notice the mutating keyword right in front of the function. If you remove the keyword, you will see the error saying “Cannot assign to property: ‘self’ is immutable”.

As I previously mentioned, the properties of a value type cannot be modified from within its instance methods by default. The mutating keyword is in charge of letting the instance know that the method is actually mutating the properties.

On the other hand, reference types such as classes are mutable. Unless the properties of a class are declared as constants, you can change the properties’ values. In this case, it doesn’t matter which you use let or var to store a class instance since it just stores the reference. Thus, changing the value of the reference doesn’t mean it changes the reference itself. In other words, even if you change the value, the place in the memory where the instance is pointing at doesn’t change.

3. The Speed of Process: Stack and Heap

Generally, structs are faster than classes when it comes to the speed of the process. That is because of the differences in their data structures.

Structs use the stack data structure. There are only two operations, push and pop. This structure is like stacking books. When you add an item to a stack, you put it on the top (push). When you remove an item from the stack, you always remove from the top (pop). That is why a stack is known as LIFO(last-in first-out) structure.

How this structure works for value types in Swift is simple. For instance, imagine you create a stack of function. When you call a function, it is added on the top of the stack. When the function returns, it is removed from the stack.

In contrast, classes use the heap data structure. The heap is a large pool of memory where the system can request an allocated memory from. Unlike the stack, the heap doesn’t automatically remove the data. This makes allocating and removing memory from the heap slower than the stack.

4. Which Should You Use?

Now you might be wondering which one should you use. Apple recommends that you go for structs by default since structs in Swift can store the same kinds of data. However, I would like to introduce three possible consideration from raywenderlich.com before you make your decision.

1) Values vs Objects

If you are using structs, structs are regarded as the same if they have the same value. On the contrary, objects have unique identity if you’re using classes. Even though you have two objects which have the same values, they are not regarded as the same object.

2) Speed

If you are creating many instances in a short period of time, it’s better to use structs because you can boost the process in that way. For example, if you want to calculate the distance of a running route using many GPS based waypoints, structs would be the best option in that case.

3) Minimalist Approach

This strategy is basically that starting with structs if you have some difficulties to choose structs or classes, and change it to classes if necessary. For instance, you can keep on going with structs if you are using just simple data or the data will never be changed. However, if you want to update your data or add methods to your data so that it can update its own state, you can change your structs to classes. Fortunately, the similarity of structs and classes in Swift makes it easier to change one from another. That’s the beauty of this strategy.

That’s everything for this article. If you have questions or suggestions, please feel free to leave a comment.

References:

The Swift Programming Language Swift 4.2 — Methods
https://docs.swift.org/swift-book/LanguageGuide/Methods.html

Apple Developer Document: Choosing Between Structures and Classes
https://developer.apple.com/documentation/swift/choosing_between_structures_and_classes

raywenderlich.com: Reference vs Value Types in Swift
https://www.raywenderlich.com/1506-reference-vs-value-types-in-swift-part-1-2

raywenderlich.com on Udemy: iOS 11 and Swift 4 for Beginners: 200+ Hands-On Tutorials — Section12 Classes vs Structures
Note: I think it’s updated to iOS 12 and Swift 4.2 now (Oct 2nd, 2018)
https://www.udemy.com/share/100sCwAEYbdFlRTHw=/

Swift Programming: The Big Nerd Ranch Guide (2nd Edition)
https://www.bignerdranch.com/books/swift-programming/

--

--

Kenta Kodashima
Kenta Kodashima

Written by Kenta Kodashima

I'm a Software Engineer based in Vancouver. Personal Interests: Books, Philosophy, Piano, Movies, Music, Studio Ghibli.

No responses yet