Transcript from the "Pass by Reference" Lesson
>> We're gonna go back to our pointers.go file and talk a little bit more about how to fix the behavior we saw in our describe group function, where we weren't able to modify that variable in a permanent way. And I comment out our current logic real quick, all of the function main Move down to a couple different examples down here.
[00:00:33] So in our main function line 40, We're establishing that a variable name is set to the value of Elvis. We're calling changeName, which accepts a name as a string, and then we're printing that to the console. In our changeName function, we are passing in one argument, which is a string, and simply modifying that variable.
[00:00:56] So if it starts out lowercase, we want it to end up uppercase. If we run this now, you'll see that even though we're calling strings.ToUpper on line 37, that variable is still coming back with just the capital E. Nothing else has been modified. And so this is the demonstration once again of how in Go, we are passing a variable by its value, not necessarily its memory location.
[00:01:26] Cool. So as we just recently talked about, if we know we wanna modify the address location itself, I'm gonna start with my change name here. I don't just want the copy of the value, I want the actual address. And so the symbol for that was a for address.
[00:01:46] So I'm gonna change name instead of just Elvis. Go find me that address and pass that to our function instead. If I were to save and run it just as is, we're gonna get an error. We're saying like, hey, you can't pass a function it's expecting a normal string.
[00:02:04] What turns out to be the address of that variable where it lives in memory. And so you recall if we're talking about a type name, and we put the asterisk before the type name, we are telling Go that we expect the type of this variable to be a pointer, to be an address.
[00:02:20] So you change that to be a star. Cool, and now you'll see that our error has changed to line 21, sorry, line 37, which is here we're saying strings.to upper, and we've got this n. But now we're trying to call to upper on an address on that like weird, convoluted series of data.
[00:02:42] So in order to change that, we need to dereference it and be like, okay, cool. I know you gave me an address, but the thing I really wanna modify is the actual value that lives here. So I'm going to refer to that variable using the asterisks so I could actually get that value back.
[00:02:56] Now, you notice when we run this again, our value has been permanently changed to capital Elvis. And so this is a super interesting aspect of go. And if you think about how you pass variables around in an application, right now we're talking about a single string, which doesn't take up a lot of space.
[00:03:14] It's not a big deal. But there are times when the actual data you're passing around is a huge amount of information. It's like a whole section from a database. You made a query and you're passing along an entire JSON response or something like that. And so whether or not you're passing a copy of the value or the actual memory location, it can be very different in terms of how expensive it is to pass that information around.
[00:03:36] For instance, if you have a huge amount of data stored in location A in your memory, giving around that address versus passing around that whole chunk of data is a little bit cheaper to do in your application. Let's look at one more example of how to modify various pieces of information using pointers.
[00:03:56] I'm gonna create a new main function down here to work from. And we're gonna talk about pointers and structs. So let's say we have a struct, that I wanna call Coordinates. In my struct, I just have two coordinates. I have an X and a Y. Let's make them capitals.
[00:04:17] And both of these are set to float64 types, like coordinates on the map. Capital C, let's add a comment to make sure Go linter is happy, Longitude. So first thing we wanna do here is establish an actual instance of our coordinates. Set it up here. Let's say var c = Coordinates.
[00:04:45] Our X value is 10, which is not a real latitude, but let's go with it, and Y which is set to 20. When you are creating an instance of a struct, you need to wrap your initial data in curly braces. And make sure that your casing matches because our attributes are both capitals.
[00:05:13] We need those to be capital X and capital Y. So now we have an insistency of our coordinates where we have an X value of 10 and a Y value of 20. If we wanted to update what's happening in our main function here, let's set a variable to pointerCoordinates.
[00:05:32] Let's change that. Let's say, coordinatesMemoryAddress which is a verbose variable to demonstrate what we're talking about here. But the coordinatesMemoryAddress is going to be set to, The actual address location of a variable c. We haven't used it yet, so we're getting yelled at, but that's just fine. And then here we can say.
[00:06:06] CoordinatesMemoryAddress.X. If we wanted to modify the X value and change it to 200. If we print that to the console. You'll see now we get this &220. If I take out that ampersand on the c line, there in line 53, you'll notice that everything is still actually modified permanently.
[00:06:44] And that's because if we were to actually try to get a little more verbose and add the ampersand and the star sign and while we're doing a strux. Go give's us a little bit of a loophole just with strux where Go is going to assume you mean the actual struct behind the scenes.
[00:07:06] So without having to dereference it or add that ampersand, we are actually getting the address. And the actual value in memory that we can modify permanently without having to be more explicit.