Swift is a multi-paradigm programming language that offers a handful of features and great tools to work with. In order to take benefit from it, you need to understand the underlying concept of each feature. Today, I will unleash some of the tricks of using semantics of different types. Let’s get down to the nitty-gritty of this concept.
You are probably familiar with value and reference types in swift. Value types in Swift include structs, enums, arrays and other native types. But I am going to use struct here as an example. This concept applies to all other value types as well.
Pro Tip: Fire up a playground and see the results for yourself 👨💻
struct Position {var x: Intvar y: Int}
So, here we have a struct named Position along with two variable store properties x and y. Let’s create some objects of this type and try to modify their properties.
var p1 = Position(x: 1, y: 2)var p2 = p1p1.x = 2print("\(p2.x)")
You might all ready know this the output of it but let’s talk about it anyway. Here we have an instance of Position assigned to p1, then we assign p1 to p2 (classical example of value type). If we change the value of p1, it won’t effect p2 because it’s value type. So basically, p1 is not assigned to p2, instead p2 has it’s own copy of same data.
Let’s take another example:
let p3 = Position(x: 3, y: 4)p3.x = 5 // compiler throws error
Can’t we modify the properties of p3? 😲
When you assign a value type to a constant, you create an immutable value that cannot be changed. Now this has nothing to do with the underlying properties even though they’re variables. Once a value is assigned to that constant using the box analogy that constant is closed. 🔒
This should make intuitive sense based on what you know so far and might seem like old news, but bare with me. To further prove this point, let’s take another example.
struct AnotherPosition {let x: Doublelet y: Double}
var p4 = AnotherPosition(x: 4, y: 6)p4.x = 5 // compiler errorp4 = AnotherPosition(x: 3, y: 1) // valid statement
In this case if we try to change the x value on p4, this doesn’t work either. This is because the container that holds the value is a variable. So we can assign an entirely different value to it if we wanted to. But the properties of the underlying values are immutable since they are constants.
Time for some silver bullets 🎯
We will start with a trivial example, not a classic one 🏛️
class Machine {var make: String
init(make: String) {
self.make = make
}
}
var m1 = Machine(make: "M1900")m1.make = "M2000"
In the above example, we have a reference type Machine with a stored variable property. If we modify m1.make, compiler won’t complaint which is obvious.
To see the difference from value semantic, let’s take another example:
let m2 = Machine(make: "M2100")m2.make = "M2300"m2 = Machine(make: "M2500") // compiler error
So, you can change the underlying properties on a constant here because we’re working with that same object. That means the reference to the object doesn’t change but the storm properties can be changed pretty easily. That’s awesome 🎉
Now that we looked at certain aspects of value types that might be tricky and concepts regarding reference types that might have eluded us. What happens when we mix those two types together?
In the above example, we have modeled User (reference type) with some underlying properties (value types). In this case, if we wish to update unit number of user’s address compiler will complaint as its a constant property of value type. 🚫
On the other hand, if we simply assign new address, it will work. None of this should be news for you anymore. We need to be more careful when modeling mixed semantics and always make your design flexible.
Now we’re geared up to face the music 🏁. We’ve gone through variance of semantics and some handy tricks to cater every situation. We used to believe that variables can change and constants don’t. As you can see now, this isn’t as cut and dry and it really depends on whether your object is a value or a reference type.
Feedback,👏 and get in touch on twitter @khfarooq.
Thanks for reading!🎖️