Golang Tutorial #18 - Mutable & Immutable Data Types

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hello everybody and welcome back to the goat length tutorial so in this video we're going to talk about mutable versus immutable data types and then a few strange behaviors that some data types in golang exhibit so let's go ahead and get started now the first thing i want to show you is kind of a primitive example of something we've seen before and i just want you to take a guess at what's going to happen so if i say y colon equals x like that and then i say y equals 7 and i go fmt dot print line x y what is going to print to the screen is my question for you when i run this code so i have the variable x i make that equal to 5 i set y equal to x and then i change the value of y to 7. so what is going to print out well let's have a run here and just look at it and then i'm going to talk to you about why this happens okay so we get 5 and 7. now that seems pretty straightforward i'm assuming 99 of you guessed that but why well when i say variable x is an integer of value 5 and then i assign y to x what i'm really saying is y is equal to the value of x which in this case is 5. then i say y equals seven so i change the value of y and when i print this out obviously we get five and seven makes sense great okay so keep that in the back of your head that this worked we understand that and that is mostly because this is what's known as a immutable data type so we have immutable immutable data types and immutable data type means not changeable and a mutable data type means changeable so when i say y coord equals x what i'm really saying is y is equal to the value stored in x which makes it equal to 5. this line of code does not bind x and y together meaning that any change to y affects x and any change to x affects y that's not true but now what i want to show you is a different example using a mutable data type as a slice so i'm going to say var x and i'm going to say int like that equals int 3 4 5. so what i've said now is let's make a new slice of x it's slice of ins and it has three four five and then what i'm going to say is y coin equals x and i'm going to say y zero equals a hundred okay so now what do you think is going to print out to the screen does me changing x change y or does me changing y change x are they bound together somehow and if so why so let's run this and have a look that's strange so we actually see here that i printed x and then i printed y and nowhere here did i change the value of x right x was just equal to 3 4 5. all i did was i set y equal to x i modified y and somehow that changed x now that's because a slice is a mutable data type although that's not the only reason and some of the behavior of a slice which i'll discuss to you later is that when i say y is equal to x what i'm really saying is that y is equal to the slice that x is pointing to so what that means is that x and y are really just pointing to the same variable so the same underlying variable and if you change x or you change y you change both of them now i'm going to draw a big example to really illustrate how this works for you in a second so don't worry but that's the basic idea behind this now that is known as a mutable data type something that is changeable now this is weird because there's some mutable data types that don't behave like this but for now what you can understand is that when we use a slice and when we use a map and we do something like this what we're really going to do is just make another name for that map or for that slice so when i said y colon equals x you can almost think of this as just y being another name for x which means that if i modify y i modify x and if i modify x i modify y i've kind of just made a i don't want to say a copy but just another pointer to this underlying slice so any change to x or y will change this slice which will in turn change both of them again i'm going to draw an example in a second but this behavior for our current understanding applies to slices and maps so if i put a map here so if i actually go map string int and then we'll make that equal to map string int and let's just do hello colon 3 and then what i do is y colon equals x and i say y you know y y why not equals 100. let's print this out and see what we get now let's have a look and we get map hello 3 y100 map low 3y 100 so me modifying y here modified x right notice that that's what happens when we use a slice and when we use a map this behavior can be expected that when i just assign y equal to the variable x or equal to whatever the original map was all i'm really doing is giving another name to that map or to that slice and any modification to either of these variables will change both of them right and if i go here and i change x and i just add a key let's just do the string seven y naught is equal to seven uh let's have a look at this now and you'll see that that will change y as well so notice that both of them get that new key seven inside of them okay so that's how that works for maps and in slices now let me show you this with arrays because arrays are a bit different so if i go and i make an array which is a fixed length remember of ins and we'll change this to just be 2 here and let's just put a few in so we'll do 3 4 we need 2 n's in there i say y colon equals x and i say y 0 equals 100 and we print this out at the bottom of our screen here let's have a look then what we get is 3 4 and 104. so when i assign y equal to the equal to x which i'm doing here this does not follow the same behavior i just showed you with those what is it slices and maps in fact what this actually does is make a copy of this array stores it in y so now when i modify y i'm not modifying x because y points to its own copy of this array 3 4. so that's something important to understand this is going to change based on what data types you're using but for now just understand that the only ones that behave weird where you you can change both of them from different variables is uh the maps and the slices now an array is actually a mutable data type as well so a slice a map and an array are known as mutable data types and what that really means is that they can change now the reason they can change is because well i can do this i can say y 0 equals 100 i'm modifying this type without actually creating a whole new thing i'm just modifying one value inside of it and same thing with a slice i can do that and same thing with a map i can do that so that's what mutable stands for now mutable doesn't necessarily dictate the behavior i've just shown you here but it's something to import and understand that immutable data type can change where an immutable data type cannot i can't just do like if i have you know let's say z colon equals nine i can't just do like z plus 6 that doesn't change z to be equal to 15. i would have to reassign the value of z so z equals z plus 6 or z plus equals 6 to actually change its value whereas here i can just modify specific parts so now let me hop over to my drawing tablet and i'm going to show you why this actually happens all right so i'm on my drawing tablet now and i'm just going to do a little example to show you what actually happens on our computer's lower level and kind of behind the scenes when we write the code that i just illustrated to you and this is hopefully going to explain to you why we get that strange behavior with slices and maps or we're not just making a copy but we're actually pointing back to that same original slice or same original map so let's have a look here let's go x colon equals let's just make a slice of ins this is just for example purposes and let's make that 1 3. okay so we have x is equal to that now let's write y colon equals x and let's write y zero equals a hundred and then let's do x zero equals a hundred and let's go through all these lines and see what actually happens okay so on the right hand side of my screen here i've drawn a little box that i've labeled ram now this is my computer's memory and what i'm going to do here is show you what actually happens in the computer's memory when we execute these lines of code now i want to make this very clear this is not an accurate complete depiction of what's actually going on this is a very high level understanding the point of this is just to give you some kind of illustration and visual as to why this behavior that i've discussed actually happens so please don't assume that this is like the perfect representation because that would take a lot longer to explain okay so when we execute the line x colon equals the slice int one three what happens well there's two things that actually happen here the first thing we need to do and i talked about this when we talked about slices is we actually need to make the underlying array for this slice now i'm not going to do that here but you can imagine that the first step is actually to create an array of size 2 with 1 and 3 inside of it and then make a slice that points to that array now i'm not going to make the array i'm just going to imagine it already exists but the first box that we're going to draw in a ram so the first thing that actually gets entered inside of there is some box gets labeled with some numeric digit i'm just going to label this um like three we'll just say this boxes id is three because each box in our computer's memory or ram has what's known as like a label or it has some id it has some numeric value that represents it ideally so we have that so we'll say okay box three and what this is going to be equal to is exactly this slice so it'll be equal to a slice so we'll just put this in here int and then one comma three okay so we make a box it's labeled some random thing and then it is equal to the actual value that we're storing in the variable then the next thing we do is we make a box i'm going to label this box x because that's the variable name that i've had here and then inside this box i actually put the address or the label of the box that stores the slice so notice here that what i've done is i've made two boxes i didn't just make one box that said x and was equal to the slice i made some box which was labeled something doesn't really matter what it was then i made another box that was labeled this variable name and it stored the value 3 inside of it now 3 corresponds to where the slice is that x is holding so this is kind of our link right so x goes to 3 3 goes to 3 and that gives us our slice so whenever we're accessing or dealing with x we first have to get the value out of x and then we have to grab wherever that box is to get the slice that we're actually going to deal with so i hope that makes sense but this is the basics in our computer's memory great so that's this line of code here complete so now let's do this one y colon equals x so when we do y coordinates x what happens is we copy the contents of x into y so i make a box called y and then inside of here i put whatever was inside x which was 3. there we go so now we have this same link right because i've just copied whatever x was storing so since x was just storing the link or the address or the box that has the slice in it now y is storing that too so when i want to access this slice well what i do is i go and i look at the value inside of y and then i look at that box and then i get the slice so a very similar thing happening when i use y so now let's look at what happens when i do y 0 equals 100 well like i just discussed if i want to modify a value or i want to change anything or access it i first need to look in the box y and see where that slice is being stored so this slice is being stored in box three so let's go to box three which is right here and let's make this a hundred so let's change that first value to be a hundred great now what happens to x well x is still pointing to this box so that means that i have modified x because x is pointing to this box i modified this box so in turn i modified x and that's the basics behind how this works instead of storing a value like in the slice as two separate things inside of both x and y that have two different values and can change it's just being stored in one location so whenever i modify that location anything that's pointing to that location will in turn be modified so that is why x and y get modified now what happens when i do x 0 equals 100 well sorry this should have been x1 let's imagine that's x1 well then i would come here to this box and i would modify this to 100 so in turn i would modify y because y is pointing to that box so that is kind of how that works we have that pointer and that's the idea behind why that actually operates now this works the same for maps so you can imagine that if i just change this to a map definition we get the exact same result happening in my computer's ram if we're doing something like this now let me show you an example with a immutable type so something like an int and show you what happens there so i'm going to redraw ram we'll just make a little short one this will be a much quicker example and on the side of my screen here i'm just going to say x colon equals seven y colon equals x and then y equals 9. so when i do this what happens in my computer's ram and i'm going to go faster here is i actually make a box called x and it just stores the value 7. so rather than having this kind of pointer system that we had before we just store the value directly with x right so x is 7. then what i do is i say y colon equals x okay great so i say y and i copy the contents of x into y so now i put 7 here so y is equal to 7. notice how i have copies i have two 7s here it's not just 1 7. so when i change y to be 9 now so let's scribble that out y becomes 9 it does not affect x because they're storing the value directly inside of them now if we had a situation where we were storing that value in its own box like say that box is labeled one and we put seven here and these both had one in them right then if i was changing this yes i would change both of them but that doesn't happen with ins with strings with floats with booleans and with arrays as well those data types follow what i just showed you where they just store copies of themselves so when you assign y colon equals x and it's one of those data types i mentioned it just copies the contents into a new variable it doesn't just point to where the contents are so i hope that made sense and that is pretty much my explanation of mutable versus immutable data types now i'm going to show you one last thing that hopefully should make this even more clear just with a function and this is something common that you might see all right so the example i want to show you now is what happens when i make a function that accepts a mutable data type like a slice or a map this isn't going to apply to arrays just the ones that follow those weird behavior that we discussed before so let's say funk change first let's say that this takes some int slice so let's actually say sorry slice ins and it doesn't return anything but what it's actually going to do is just change the first element of this slice so it's going to say slice 0 equals a thousand nice so now inside of here i'm going to make a slice so i'm going to say var x in slice equals in three four five okay and then i'm going to call change first and i'm going to pass x and i'm going to print x before and after so i'm going to say fmt.printline x and then we'll copy this and we'll put it here now just have a look at what's happening we have this function change first takes a slice of integers and then changes that first value to be a thousand then here we print x we call change first we print x again let's look at this and see what happens okay so we get three four five and then a thousand four five so me passing x through this function i was actually able to modify x down here now the reason for that is because when i pass x in as the argument or the parameter or whatever you want to call it what is really happening in this function is it says slice is equal to x right it says the slice variable becomes equal to x whatever that's the value i passed in right and now we say slice zero equals a thousand well we're doing the same thing as the example where i showed you that i assigned y equal to x since slice is simply equal to x and x is equal to the pointer to this slice well what i'm doing is i'm modifying x and i'm modifying slice because i'm modifying that underlying slice so when i come back down here just because this function was in a different place it doesn't matter i still modified the value in x so this is something that you can do you can modify slices um and maps and a few other data types that we haven't mentioned yet from functions so i can make functions like change first or delete last or something like that that will modify the contents of whatever you pass in without actually having to return a value so i didn't return a new slice i simply modified the existing slice and that changed it out here and anywhere else that it was being referenced or had a variable assigned to it so with that being said i think i'm going to leave the video here i know this is a confusing topic so feel free to leave some questions if you have them i hope you guys enjoyed if you did make sure you like subscribe and i will see you in the next video
Info
Channel: Tech With Tim
Views: 13,978
Rating: undefined out of 5
Keywords: tech with tim, golang tutorial, go programming language, golang mutable, mutable golang, immutable golang, mutable, immutable
Id: vtYTl4pNDSI
Channel Id: undefined
Length: 17min 44sec (1064 seconds)
Published: Tue Jun 02 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.