In the process of learning Golang recently, I found an interesting thing. Some articles say that slice is passed by reference when passing parameters in function calls, while others say it is passed by value. Why do people recognize the same thing differently? In order to understand its essence, I conducted the following research:

  1. How do variable names, variable values, and variable addresses look in memory?

  2. What is the definition of a pointer? What is the definition of a reference? What’s the relationship between the two?

  3. What is the difference between value passing, pointer passing and reference passing?

  4. Is slice passing a function by reference in Go? If not, why can I change its value inside the function?

In order to avoid writing too long, I feel sleepy after reading it. I divide it into two articles to explain this problem. In this article, I first solve problems 1 and 2, and the next part explains the remaining problems.

Variable name: a programmer’s nickname for an address

When I was in school, I was told that variables are stored in memory, and memory is like rows and rows of drawers, and each drawer has a number on it. We define a variable, and we put the things we want to put in the drawer with the corresponding number. Int a = 10

The name of the variable is A, the value of the variable is: 10, and the address of the variable is: 0x 00000001. So the question is, the value of the variable we know is in the drawer (memory), each drawer has a number (address), but where is the name of the variable A stored? Or does it exist in memory?

If you want to store the name of a variable in memory, you must allocate space for it, and the space to store it has an address. Does the address have to be stored somewhere for the program to find it? If this is the case, the code is not written at all and will not run.

In fact, the variable name is only for programmers to see, let us write code to know what the variable is used, can call the value of the variable through the name. Because if you were given the address 0X 23004123, do you know what that means? When the code is compiled and eventually converted to machine code, the variable names we define don’t exist, just addresses and values.

Pointers are actually quite common

With that in mind, there is one more special variable: the pointer variable. What is a pointer variable? For example, int* pa = &a indicates that pa drawer contains the address of A, and its type is int*. Continue to look at the picture:

It is important to note here that the relationship between pointer PA and A is as follows: Drawer A contains variable value 10, and drawer PA contains variable address 0x00000001.

A reference is another name for a variable

Moving on to references, references and Pointers are often confused because they behave very strangely and look very similar.

Since the concept of references was introduced in c++, the following code uses c++ and is just some printing, so feel free to read on

int main() { int a = 10; // int * pa = &a; // int &b = a; Printf ("a: %d\n", a); // a: 10 printf("*pa: %d\n", *pa); // *pa: 10 printf("b: %d\n", b); // b: 10 *pa = 20; printf("a: %d\n", a); // a: 20 printf("*pa: %d\n", *pa); // *pa: 20 printf("b: %d\n", b); // b: 20 b = 30; printf("a: %d\n", a); // a: 30 printf("*pa: %d\n", *pa); // *pa: 30 printf("b: %d\n", b); // b: 30 a = 40; printf("a: %d\n", a); // a: 40 printf("*pa: %d\n", *pa); // *pa: 40 printf("b: %d\n", b); // b: 40 return 0; }Copy the code

We can see from the above code that both Pointers and references have the same effect: they both have the ability to change the value of A. As mentioned earlier, the pointer holds the address of A, and by dereferencing it, it actually opens the drawer of A, so it can be changed. So how do you get the references? Note one detail here: *pa = 20; C = 30; A = 40. We can see that c is operated in the same way as A: we use the variable name directly, but pa has to be dereferenced to change the value of A. If pa=20, this simply changes the value of PA, which points to another address.

Why do references and variables operate in the same way? Let’s look at the definition of a reference:

A reference is an alias for a variable, and you operate on a reference exactly as you would on a variable directly.

So what does an alias mean?

See? A is B, b is A. The system does not allocate extra space for reference storage, or even simply that the alias is only for programmers, who at the machine code level will become the address: 0x 00000001.

Mark is witness

How much do you understand from the above analysis? Or are you dubious about Pointers and references? It doesn’t matter, just write some code to prove it, and what we’re going to prove is:

  • A reference is an alias for a variable, so its address should be the same as the variable;

  • A pointer holds the address of a variable, so its value is the address of the variable, and its own address is different from that of the variable.

To prove this, the program is designed as follows: define a variable, assign a value to a pointer and a reference, and then check their corresponding value and address.

int main() {    int a = 10;    printf("%d\n", a);    printf("%p\n", &a);        printf("~~~~~~~~~~~~~~\n");    int * b = &a;    printf("%p\n", b);    printf("%p\n", &b);        printf("~~~~~~~~~~~~~~\n");    int & c = a;    printf("%d\n", c);    printf("%p\n", &c);        return 0;
}Copy the code

Get the output:

10 // Address of variable A ~~~~~~~~~~~~~~ 0x7ffee3C7a768 // pointer value, Is the address of variable A 0x7ffee3C7a760 // The address of the pointer variable itself ~~~~~~~~~~~~~~ 10 // The value of variable A 0x7ffee3C7a768 // references the address of variable C, exactly the same as the address of variable ACopy the code

Printf (“%d\n”, *b); printf(“%d\n”, *b);

summary

  • Variable is composed of three parts: variable name, variable value and variable address;

  • Variable names are really just for programmers to look at; they don’t exist in compiled code;

  • A pointer variable is a variable that stores the address of another variable, and the system allocates memory for that address.

  • A reference is actually an alias for a variable that has the same address as the variable.

The next preview:

  1. What is the difference between value passing, pointer passing and reference passing?

  2. Why is slice a reference type?

  3. Is slice passing a function by reference in Go? If not, why can I change its value inside the function?