[introduction] go special reference type: value passing / pointer passing / reference passing

Time:2021-3-10

Conclusion: in golang, only value can be used to transfer function parameters

Variable name / value / address

var a = 10
log.Printf (% P / N ", a) // the variable address is assumed to be 0x00000001

Variable name a, variable value 10, variable address 0x00000001

Pointer / reference

Pointer variables store the addresses of other variables. In C + +, reference is another name of variable

Variable name itself has no effect, just equivalent to code, which is beneficial to programmer programming. Reference as alias essentially points to the same memory address. Pointers essentially take up a small amount of memory

pass by value

Value passing is a deep copy. The copy passed inside the function does not affect the arguments outside the function

When the function is called, the actual parameters are deeply copied and then pressed on the stack

Pointer passing

A formal parameter is a pointer to the address of an actual parameter. When a formal parameter is pointed, it is equivalent to an operation on the actual parameter itself

Reference passing for C++

Reference passing in C + + essentially passes the address of an argument to a function, similar to pointer passing

Function calls in go only pass values, but there are reference types such as slice, map and channel

array := []int{1,2,3}
arrayslice := array[:]

“Special reference types” in go

Can passmake()All created are reference types, as shown in the figure belowsliceandmapsliceIt is essentially a pointer type to the array memory space:

type Slice struct {
    Point // memory address
    len int
    cap int
}

So essentially rightsliceThe assignment of slices is essentially the assignment of theSliceThis structure is a deep copy of thePointNaturally, it points to the same space. Although it’s value passing, it’s essentially twoSliceObject, the object passed is a pointer, the pointer is the same, so it is a special value passing.mapIn the same way

The examples in golang can reflect the slicing characteristics more intuitively

Func printaddr (s [] int) {// print array address value parameter
    log.Printf("printAddr:%p\n", &s[0])
}

Func printaddrpoint (PS * [] int) {// print array address pointer parameter
    log.Printf("printAddrPoint:%p\n", &((*ps)[0]))
}

func main() {
    Array: = [3] int {1, 2, 3} // array commit 1
    //Array: = [] int {1, 2, 3} // slice commit 2
    log.Printf("array:%p\n", &array)

    Arrayslice: = array [:] // slice
    log.Printf("arrayslice:%p\n", &arrayslice)

    printAddr(arrayslice)
    printAddrPoint(&arrayslice)
}

Console output:

2020/08/07 15:15:35 array:0xc00000e3c0
2020/08/07 15:15:35 arrayslice:0xc000004620
2020/08/07 15:15:35 printAddr:0xc00000e3c0
2020/08/07 15:15:35 printAddrPoint:0xc00000e3c0

In essence, it is because slice passing is still value passing. Although the structure itself is not an address, it contains all the starting addressesarray[0]This also explains why the three are the same

Comment out commit1, uncomment out commit2, run again, and the result is as follows:

2020/08/07 15:22:42 array:0xc0000044a0
2020/08/07 15:22:42 arrayslice:0xc000004640
2020/08/07 15:22:42 printAddr:0xc00000e3c0
2020/08/07 15:22:42 printAddrPoint:0xc00000e3c0

guessarray[0]My address should be0xc00000e3c0, verification:

func main() {
    Array: = [] int {1, 2, 3} // array
    log.Printf("array[0]:%p\n", &array[0])
}

Console output:

2020/08/07 15:37:19 array[0]:0xc00000e3c0

arrayandarray[0]The address of is inconsistent.array[0]Like the address of the zeroth element of other slices, we can draw a conclusion after continuing to try

1. The array address is equal to the address of the first element of the array, which is consistent with C

2. The address of the slice (structure) is inconsistent with the address of the first element of the sliceGuess when declaring slices, the order is to create an array first, and then initialize the slice structure as an array reference?

Reference link

Is parameter passing in go language a value or a reference

I have these ideas about variables

Is there reference passing in function parameter passing in golang?

Understand the underlying design of slice in golang