This is a creation in Article, where the information may have evolved or changed.
Does Go have any reference to the argument (vs C + +)
Three ways to pass parameters in C + +
Value passing:
One of the most common ways to pass a parameter is a copy of the argument, which changes the parameter in the function without affecting the parameters outside the function. It is generally a function that modifies the parameters internally and does not want to affect the caller by passing the value.
Pointer passing
A parameter is a pointer to the address of an actual parameter, as the name implies, the action that the parameter points to in the function, and the argument itself is modified.
Reference delivery
In C + +, a reference is the alias of a variable, which is actually the same thing, and the same address exists in memory. In other words, regardless of where the reference operation is, the referenced variable is manipulated fairly directly.
Here's the demo:
#include <iostream>//value passingvoidFunc1 (intA) {Std::cout <<"value pass, variable address:"<< &a <<", Variable value:"<< a << Std::endl; A + +;}//Pointer passingvoidFunc2 (int* a) {std::cout <<"pointer pass, variable address:"<< a <<", Variable value:"<< *a << Std::endl; *a = *a +1;}//reference deliveryvoidFUNC3 (int& a) {Std::cout <<"pointer pass, variable address:"<< &a <<", Variable value:"<< a << Std::endl; A + +;}intMain () {intA =5; Std::cout <<"Variable actual address:"<< &a <<", Variable value:"<< a << Std::endl; Func1 (a); Std::cout <<"value passed after operation, variable value:"<< a << Std::endl; Std::cout <<"Variable actual address:"<< &a <<", Variable value:"<< a << Std::endl; Func2 (&a); Std::cout <<"After a pointer pass operation, the variable value:"<< a << Std::endl; Std::cout <<"Variable actual address:"<< &a <<", Variable value:"<< a << Std::endl; Func3 (a); Std::cout <<"After the reference pass operation, the variable value:"<< a << Std::endl;return 0;}
The output results are as follows:
变量实际地址:0x28feac, 变量值:5值传递,变量地址:0x28fe90, 变量值:5值传递操作后,变量值:5变量实际地址:0x28feac, 变量值:5指针传递,变量地址:0x28feac, 变量值:5指针传递操作后,变量值:6变量实际地址:0x28feac, 变量值:6指针传递,变量地址:0x28feac, 变量值:6引用传递操作后,变量值:7
Parameter Passing in Go
The above describes the C + + three kinds of parameter passing way, value transfer and pointer passing is easy to understand, then Go is not also have these methods of communication? This has been controversial, but compared to the concept of C + + reference passing, we can say that Go does not have a reference delivery method. Why do you say that, because Go does not have the concept of a variable reference. But go has a reference type, which is explained later.
Let's look at an example of Go value and pass pointer:
package mainimport ( "FMT" ) func main () {a: = 1 FMT. Println (, &a, , a) func1 (a) fmt. Println (, a" fmt. Println (, &a, , a) Func2 (&a) fmt. Println ( "pointer pass operation, variable value:" , a)}//value passed func Func1 (a int ) {a++ fmt. Println (, &a, , a)}//pointer passing func Func2 (a *int ) {*a = *a + 1 FMT . Println ( "pointer pass, variable address:" , A, , *a)}
The output results are as follows:
变量实际地址: 0xc04203c1d0 变量值: 1值传递,变量地址: 0xc04203c210 变量值: 2值传递操作后,变量值: 1变量实际地址: 0xc04203c1d0 变量值: 1指针传递,变量地址: 0xc04203c1d0 变量值: 2指针传递操作后,变量值: 2
As you can see, the Go primitive type's value passing and pointer passing is no different from C + +, but it does not have the concept of a variable reference. How do you understand the reference type of Go?
Reference type of Go
In Go, reference types include slices, dictionaries, channels, and so on. In the case of slices, is it a reference to pass a slice?
As an example:
package mainimport ( "fmt")func main() { make([]string1) m1[0"test" fmt.Println("调用 func1 前 m1 值:", m1) func1(m1) fmt.Println("调用 func1 后 m1 值:", m1)}func func1 (a []string) { a[0"val1" fmt.Println("func1中:", a)}
The output results are as follows:
调用 func1 前 m1 值: [test]func1中: [val1]调用 func1 后 m1 值: [val1]
The changes to the slices in the function affect the values of the actual parameters. Does that mean that the reference is passed?
In fact, to answer this question, we have to figure out whether the calling function slice has m1
changed. First, we need to recognize the nature of the Chu slice.
A slice is a description of an array fragment. It contains a pointer to an array, the length of the fragment.
That is, we are not printing the slice itself, but the array that the slice points to. To give an example, verify that the slices have changed in the end.
package mainimport ( "fmt")func main() { make([]string1) m1[0"test" fmt.Println("调用 func1 前 m1 值:"cap(m1)) func1(m1) fmt.Println("调用 func1 后 m1 值:"cap(m1))}func func1 (a []string) { append"val1") fmt.Println("func1中:"cap(a))}
The output results are as follows:
调用 func1 前 m1 值: [test] 1func1中: [test val1] 2调用 func1 后 m1 值: [test] 1
This result shows that the slices have not changed before and after the call. The so-called "change" in the previous example is actually a change in the elements of the array that points to the array in the slice, which may be a bit of a mouthful, but in practice. Again, the reference type's arguments are not pass-by-reference.
Want a thorough understanding of 一个切片是一个数组片段的描述。它包含了指向数组的指针,片段的长度
this sentence, interested can read this article: http://www.2cto.com/kf/201604/499045.html. Learn about the sliced memory model.
Summarize
The summary is very simple, the language also needs through the phenomenon to see the essence. And the conclusions of this article need to be remembered:
There is no pass-by-reference in Go.