Hey, it's me again, Angela from the App Brewery. Welcome to another Swift Deep Dive. 1
And in this Deep Dive, we're going to talk about immutability, more specifically, what does it mean when 2
we say that a struct is immutable? 3
Let's quickly recap some key concepts. When we create a struct in our code, 4
we're essentially creating a blueprint for an eventual object that will get created from our blueprint. 5
And in this blueprint, we get to plan ahead for how this eventual object will be. 6
For example, we create variables, such as our questionNumber. And when our variables live inside a struct, 7
that variable is associated with our struct and it's known as a property of that struct. 8
Similarly, we've created functions inside our struct. And when functions are created inside a struct, they're 9
known as a method. 10
So you can consider these properties as a way of defining what this eventual object created from the 11
struct will be like, 12
so its attributes or its properties. And the methods can be thought of as what the objects can do. 13
So when we created our QuizBrain struct, we were essentially creating the blueprint for the eventual 14
Quiz Brain that would get created, and we can take our blueprint and initialize it which turns it into 15
the actual object. 16
Now, we come on to the topic of Immutability. Swift is designed so that anything marked by the "let" keyword 17
is immutable. 18
But what does that mean? 19
Suppose you created this structure from a bunch of different Lego blocks using the "let" keyword, but 20
at some point, you decide that you want to change some aspect of it, say, the color of one of the bricks. 21
Well, unfortunately, because the structure was created using the "let" keyword, meaning it's immutable, 22
you can't just change this one brick from green to yellow. 23
Well, instead, you have to destroy the entire structure and create a brand-new one that has a yellow brick 24
there instead. 25
So the way that I think about immutability is, imagine if you created a sculpture from stone, right, 26
if you created Michelangelo's David and you decided that it should have a larger nose, 27
well, you can't just come along and chip away at the stone because the nose is already too small, 28
what you actually have to do is to completely destroy the sculpture and carve a new one with this gigantic 29
ugly looking nose. and that's how you would work with immutable objects. 30
You destroy the old copy and create a new copy that encompasses the change. 31
So how does this discussion about immutability relate back to our Swift code? 32
Well, firstly, it relates to the keywords "var" and "let." Things marked with "var" are mutable and things marked 33
with "let" are immutable. But immutability also relates to struct. With struct, Swift makes an additional 34
distinction. 35
There's a difference between mutating a struct from the outside and changing a property from inside 36
the struct. 37
Let's go back to the example of my town, so I can show you what I mean. 38
Remember when my other hero Keanu Reeves moved into my town, 39
well, I certainly remember. In this case, we changed the citizen's property from outside the struct. 40
We wrote myTown.citizens.append and mutated the citizen's property. 41
But now let me show you what happens when we try to change a property of our structure from within the 42
structure itself. 43
So suppose that we wanted to create a function inside our town struct that allows us to change the resources. 44
Suppose that in our town, we also had a method called harvest rice, and in this case, what happens is we 45
add some rice to our resources, right? 46
So this is a property of our town which is a dictionary that has a string as a key and an integer as 47
the value of the amount of resources we have. 48
So when we harvest rice, what actually happens behind the scenes is we tap into our resources, 49
we go ahead and reach in and look for the rice resource, and then we set it to equal 100 bags. 50
But in this case, we have a method that changes a property of our struct from within the struct. And we 51
get an error "Cannot assign through subscript: 'self' is immutable." 52
What does that mean exactly? 53
What's actually going on here? 54
Well, we're trying to mutate the resources property of the struct itself. 55
The code that we wrote is actually shorthand for self.resources, brackets "Rice" equals 100. 56
That's why the error message mentions "self is immutable." 57
You can think of "self" as a property gets automatically created. 58
We can always access "self" inside a method, just like how we did in our "init" function with 59
self.citizens or self.resources. 60
And it refers to an instance of the structure itself from within the structure's declaration. 61
But here's the catch, though. 62
Inside a struct, when "self" is created automatically in the background, it's defined with the "let" keyword. 63
That's why "self is immutable." 64
So if we want to mutate any property from within our structure like self.resources, then we need 65
to mark our harvestRice method with a special keyword called mutating, and then you'll see all our errors 66
will go away. 67
So now we can say myTown.harvestRice, and then we can go ahead and print myTown.resources, 68
and you can see that when this code runs, that in addition to having some wool, to begin with, we've also 69
got a bunch of rice now. Yay, foods! And the only thing we had to do is that if we're making a method that 70
modifies one of the properties from within the struct, then we have to mark that method as mutating. 71
By marking the method as mutating, "self" will behave like a "var" and we can freely change any of our struct 72
properties. And the other way to look at this is by thinking of struct as having two kinds of methods. 73
The first kind of a method is a plain method that doesn't change anything about the struct. But the second 74
kind of method is a mutating method that can change the state of the structure. 75
So given everything we've talked about, I've got a question for you. 76
Do you think you can call harvest rice if we wrote "let myTown instead? 77
Well, the answer is No. 78
When we use the "let" keyword, our struct and all its properties are immutable and we cannot call a mutating 79
function like harvestRice. 80
And that wraps up our Deep Dive on immutability. 81
See you in the next lesson.