Treehouse Intermediate Course Part 5 (Semantics)
Here we go! Haven't had the chance over the past two days so am going to do a good half an hour or so now! Last time, it was a big focus on initialisers. I've made of sense of those and hopefully I'll be able to apply that. Now we're moving on to something else - can't remember. Anyway, let's go!
Value Semantics
Value types - structs, enums etc.
Here, this constant is IMMUTABLE. You cannot then change the values! However with var (p1 or p2) you can change values, as long as the stored properties are variables (which they are!)
Value Semantics
Value types - structs, enums etc.
struct Point {
var x: Double
var y: Double
}
var p1 = Point(x: 1, y: 2)
var p2 = p1
If we change the x value of p1, then let's see what happens to p2. It does not change!
A value type is COPIED ON ASSIGNMENT!
We are copying the underlying value.
let p3 = Point(x: 2, y: 4)
Here, this constant is IMMUTABLE. You cannot then change the values! However with var (p1 or p2) you can change values, as long as the stored properties are variables (which they are!)
struct AnotherPoint {
let x: Double
let y: Double
}
var p4 = AnotherPoint(x: 1, y: 2)
p4.x = 3
Yes - of course - an error comes up!
BUT...this IS allowed!!
p4 = AnotherPoint(x: 4, y: 12)
So reassigning with lets is ok.
I've heard 'mutating the value of' - that means change the value of one of the properties after declaration of values has already happened.
I predicted the keyword 'mutating' would be needed before the function and it has now been put in. Good!
Reference Semantics
class Robot {
var model: String
init(model: String) {
self.model = model
}
}
var someRobot = Robot(model: "T1000")
var anotherRobot = someRobot
someRobot.model = "T2000"
Right so it sounds obvious but the point here is that classes are reference types - in the example above, anotherRobot is now going to change its model name. Different to value types in this sense.
let thirdRobot = Robot(model: "T3000")
thirdRobot.model = "T4000"
An excerpt from Pasan to make sense of:
- When we're assigning an instance of a reference type to a constant,
- 2:31the thing that is constant again isn't the object, it's the reference to the object.
- 2:36This means that we can't assign another instance of robot to thirdRobot.
- 2:41But we can change the underlying object as much as we want.
- 2:45Unlike value types where the object is copied, assigned a new value and then
- 2:50reassigned to the variable or a constant when we mutate the stored properties.
- 2:54None of that happens with a reference type.
- 2:57You can change the underlying properties on a constant
- 2:59here because we're working with that same object.
- 3:02Meaning the reference to the object doesn't change but
- 3:05I'm not too sure what he means here! I need to make sense of it.OK, so some of this is as simple as constants CAN change if they are a reference type. So we can actually edit the constant but can't assign another instance to that same constant.Mixed SemanticsLast bit for now!OK this was massively confusing. I'm going to read up on other stuff to make sense of it!First of all, the link that Pasan put in:Right to sum this up, it is saying that classes are mutable. This is an issue if you do not want a variable to change. With classes, copying an instance means that they "refer to a single instance of the data", so changing the value of the copy will affect the original.Eerily, this website uses almost the exact same examples as Pasan's one. I wonder which came first.... Anyway, here is the alternative example for the mixed semantics part...struct Address {let unitNumber: Stringlet buildingNumber: String}struct Residance {var numberOfRooms: Intvar address: Address}class User {let name: Stringvar residance: Residanceinit(name: String, unitNumber: String, buildingNumber: String, numberOfRooms: Int) {self.name = namelet address = Address(unitNumber: unitNumber, buildingNumber: buildingNumber)self.residance = Residance(numberOfRooms: numberOfRooms, address: address)}}let user = User(name: "Khawaja", unitNumber: "3A", buildingNumber: "209", numberOfRooms: 2)//user.residance.address.unitNumber = "3B" // compiler erroruser.residance.address = Address(unitNumber: "3B", buildingNumber: "209")So the compiler error line happens because the unit and building numbers are constants. As they are value types, you cannot just changed the stored property values. But you can by reassigning through the bottom line example.Right, the user type, where the instance is created - reference type - includes value types in its properties. That's why its mixed. Makes a lot more sense now.Well, that's been tricky but actually I think it's very simple at its core. I knew a bit about value and reference types before, but this has helped to show it in action. Reference types are dangerous in the sense that the constants are actually mutable. Having values change after copies are made could lead to bugs. Value types are simpler in this sense but don't have the same complexity and possibilities as reference types. That is what I am taking away from this!
Comments
Post a Comment