Detail the reference types in go

  • 2020-09-28 08:56:38
  • OfStack

Value types and reference types

Value types: int, float, bool, and string are all value types that use variables of these types to point directly to values that exist in memory. The value of the variable of the value type is stored on the stack. When you use the equal sign = to assign the value of one variable to another, such as j = i, you are actually copying the value of i in memory. Can be achieved by & i gets the memory address of the variable i. Copy the value

Reference types: refer to the three predefined types slice, map, and channel. Reference types have more complex storage structure: (1) the allocated memory (2) to initialize the 1 series properties such as a reference type variable r1 storage is r1 value of memory address (number), or in the memory address where the first word, the memory address is called a pointer, the pointer, in fact, there is also another one in one word.

The main difference between the two: copy operations and function argument passing.

The body begins by focusing on the types of references in go.

First of all, assignments in go are value passing

[

a := 1
b := a

x := Struct{}
y := x

]

They all have their own space in memory, which is the process of copy, so changes to one of y's attributes here will not affect x

What if we want two variables to point to the same memory? We can use the reference type:

[

y := & x

]

At this point, y is of type *Struct, so we can modify y, and after that, x will also notice a change, because y is now a reference type that points to the memory where the x structure is located

We can pass:

[

y.variable = xxx

]

To call the reference-type structure assignment directly, but note that this is go's syntax sugar, which just helps us simplify the process of getting real memory through Pointers, the complete way would look like this:

[

(*y).variable = xxx

]

*y is a backreference to a pointer and can be interpreted as *y == x.

The reason why this syntax is designed is because in go we cannot directly manipulate Pointers, like in c++ we can directly calculate the memory address and then get other memory address calculations, which is not supported in go by default

[

print(y) // get memory address data like 0x8123

// In theory you can get a new memory address, but in go it is not supported by default
newAddr := y + 4

]

Since you can't manipulate the address directly, go provides syntax sugar that lets you manipulate the memory address that the reference refers to by default when working with reference types.

Note that we can assign a value directly to a reference type, but the assigned type must also be a reference type

[

y = & Struct{} // This is ok, but not y = Struct{}

a := 1
b := & a
b = 2 // This does not work because b is of type *int

]

Special reference type

All that can be created with the make() function are reference types, such as slice and map. Although slice looks like an array, it is actually a pointer type that points to the memory space of the array


type Slice struct {
 point Point //  Memory address 
 len int
 cap int
}

So we're implementing:

[

a := []int
b = a

]

You'll notice that it looks like b and a are pointing to the same array, which they are. All assignments in go are value passes, and the assignment of slice is also a copy of the slice object, meaning that a and b are different slice objects, but they point to the same array

The same is true of map, I won't go into that.

conclusion


Related articles: