I finished the go exercise about pointers. I solved it but something doesn’t feel right.
The syntax for declaring a pointer feels backwards to me.
The mental model I built for how pointers work is:
&variable - Address of a memory location
*variable - Data at memory address.
So why then is the declaration: var p *int
This feels backwards. I feel like var p &int would be tighter? I’m sure the issue is that my mental model is incorrect but why? What’s happening under the hood that makes this syntax consistent?
Think of them as operators. &var means, "give me the address that var points to. *var means “use the data at some address”.
var foo int tells Go to set around some memory to store an int. That memory might be at location 50. If we pretend the memory is just one big array, foo = 4 writes 4 to memory[50]. We can then say println(*foo). This gets the data from foo aka read the data from memory[50] – which is 4, then use *4 to read the data at that address, ie get memory[4]. Similarly, println(&var) gets where var points, ie 50, and prints 50.
var p *int does more or less the same thing as var p int. It allocates some memory, eg memory[60] to store data and p is set to address 60. The only difference is what type of data memory[60] represents. Is that an int or a rune or a byte or a *int? In this case, we told Go that memory[60]'s type happens to be a *int.
We can then say p = &foo or p = 50 which updates memory[60] (ie p) to the number/address 50. We can now access foo to get memory[50] or use *p to get memory[memory[60]] – which are the same.
Does that help?
Note, this isn’t Go-specific. Most languages with pointers work roughly the same way.
Based on your response, I’m not sure if I communicated my confusion properly or I missed the point. I’m very sorry if the latter is the case.
I do think I understand how to use it. I just don’t understand why something is the way it is. Sorry if it feels like i’m just repeating myself.
var p *int //pointer is an address of type int. type really only tells you how big the block of data is.
var potatoes int = 3 //sets potatoes to 3, at some 'unknown' memory address.
p = &potatoes //sets p to the address of potatoes
...
...
vegetableCount += *p
What I don’t understand is why:
We access the data at an address (a pointer) with *
We get address of a variable with &
why do we declare a pointer with * eg: var p *int
when used outside of a pointer declaration * seems to be used to say: grab this block of data at this address… and & seems to say: grab the address of this variable. Why then is it: var p *int and not var p &int, since & represents addresses?
In other languages you might call it ptr or intptr. As per your example, with var p *int you would often use *p but rarely &p. If *p is common and &p is weird, then p is associated with * so let’s use that for the name? Either would make sense since you got both p = &foo and foo = *p. Using neither might be more clear ;)
The * in var p *int is not doing the same thing as the * in foo = *p. The * in foo = *p says, “treat this next this as an address” so *int says “this thing is an address”. Both & and * indicate something with addresses/pointers.
Fair enough. Sounds like I just have to accept convention. I was hoping there was a piece of the puzzle i was missing that made it more clear. I’ve seen this in other languages and it confused the heck out of me then too.