Home  >  Article  >  Backend Development  >  Go language comparison C++ reference parameter passing

Go language comparison C++ reference parameter passing

巴扎黑
巴扎黑Original
2017-09-02 11:16:131532browse

This article mainly introduces whether Go has parameter passing by reference (compared to C++). Friends who need it can refer to

Three parameter passing methods in C++

Value passing:

The most common method of passing parameters. The formal parameters of the function are copies of the actual parameters. Changing the formal parameters in the function will not affect to formal parameters outside the function. Generally, value passing is used when modifying parameters within a function without affecting the caller.

Pointer passing

The formal parameter is a pointer pointing to the address of the actual parameter. As the name suggests, when the content pointed to by the formal parameter is manipulated in the function, the actual parameter itself will be modified. .

Passing by reference

In C++, a reference is an alias for a variable. It is actually the same thing and has the same address in memory. In other words, wherever a reference is manipulated, the referenced variable is quite directly manipulated.

Look at the demo below:


#include <iostream>
//值传递
void func1(int a) {
  std::cout << "值传递,变量地址:" << &a << ", 变量值:" << a << std::endl;
  a ++ ;
}
//指针传递
void func2 (int* a) {
  std::cout << "指针传递,变量地址:" << a << ", 变量值:" << *a << std::endl;
  *a = *a + 1;
}
//引用传递
void func3 (int& a) {
  std::cout << "指针传递,变量地址:" << &a << ", 变量值:" << a << std::endl;
  a ++;
}
int main() {
  int a = 5;
  std::cout << "变量实际地址:" << &a << ", 变量值:" << a << std::endl;
  func1(a);
  std::cout << "值传递操作后,变量值:" << a << std::endl;
  std::cout << "变量实际地址:" << &a << ", 变量值:" << a << std::endl;
  func2(&a);
  std::cout << "指针传递操作后,变量值:" << a << std::endl;
  std::cout << "变量实际地址:" << &a << ", 变量值:" << a << std::endl;
  func3(a);
  std::cout << "引用传递操作后,变量值:" << a << std::endl;
  return 0;
}

The output results are as follows:

Actual address of variable: 0x28feac, variable value: 5
value Transfer, variable address: 0x28fe90, variable value: 5
After the value transfer operation, variable value: 5
Actual variable address: 0x28feac, variable value: 5
Pointer transfer, variable address: 0x28feac, variable value: 5
After the pointer transfer operation, the variable value: 6
The actual address of the variable: 0x28feac, the variable value: 6
The pointer transfer operation, the variable address: 0x28feac, the variable value: 6
After the reference transfer operation, the variable Value: 7

Parameter passing in Go

The above introduces the three parameter passing methods of C++, value passing and pointer Passing is easy to understand, so does Go also have these parameter passing methods? This has caused controversy, but compared to the concept of reference passing in C++, we can say that Go has no reference passing method. Why do I say this, because Go does not have the concept of variable references. But Go has reference types, which will be explained later.

Let’s first look at an example of passing value and pointer in Go:


package main
import (
  "fmt"
)
func main() {
  a := 1
  fmt.Println( "变量实际地址:", &a, "变量值:", a)
  func1 (a)
  fmt.Println( "值传递操作后,变量值:", a)
  fmt.Println( "变量实际地址:", &a, "变量值:", a)
  func2(&a)
  fmt.Println( "指针传递操作后,变量值:", a)
}
//值传递
func func1 (a int) {
  a++
  fmt.Println( "值传递,变量地址:", &a, "变量值:", a)
}
//指针传递
func func2 (a *int) {
  *a = *a + 1
  fmt.Println( "指针传递,变量地址:", a, "变量值:", *a)
}

The output result is as follows:

The actual address of the variable: 0xc04203c1d0 variable Value: 1
Value transfer, variable address: 0xc04203c210 Variable value: 2
After value transfer operation, variable value: 1
Actual variable address: 0xc04203c1d0 Variable value: 1
Pointer transfer, variable address: 0xc04203c1d0 Variable value: 2
After the pointer transfer operation, variable value: 2
It can be seen that the value transfer and pointer transfer of Go's basic types are no different from C++, but it does not have the concept of variable reference. So how do you understand Go's reference types?

Go’s reference types

In Go, reference types include slices, dictionaries, channels, etc. Take slicing as an example. Is passing a slice a reference?

For example:


package main
import (
  "fmt"
)
func main() {
  m1 := make([]string, 1)
  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 result is as follows:

The value of m1 before calling func1: [test]

## In #func1: [val1]

The value of m1 after calling func1: [val1]

The modification to the slice in the function affects the value of the actual parameter. Does this mean that this is pass-by-reference?

In fact, not really. To answer this question, we must first find out whether the calling function slice m1 has changed. First we need to understand the nature of slicing.

A slice is a description of an array fragment. It contains a pointer to the array, the length of the fragment.

In other words, what we print above is not the slice itself, but the array pointed to by the slice. For another example, verify whether the slice has changed.


  package main
import (
  "fmt"
)
func main() {
  m1 := make([]string, 1)
  m1[0] = "test"
  fmt.Println("调用 func1 前 m1 值:", m1, cap(m1))
  func1(m1)
  fmt.Println("调用 func1 后 m1 值:", m1, cap(m1))
}
func func1 (a []string) {
  a = append(a, "val1")
  fmt.Println("func1中:", a, cap(a))
}

The output results are as follows:

The value of m1 before calling func1: [test] 1

In func1: [test val1] 2

The value of m1 after calling func1: [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 that the elements of the array pointed to by the pointer to the array in the slice have changed. This sentence may be a bit awkward, but it is actually true. Proving once again that parameter passing of reference types is not pass-by-reference.

I want to have a thorough understanding. A slice is a description of an array fragment. It contains the pointer to the array and the length of the fragment. If you are interested, you can read this article: http://www.jb51.net/kf/201604/499045.html. Learn about the memory model of slicing.

Summary

The summary is very simple, and language also needs to see through the phenomenon to see the essence. There is also the conclusion of this article that needs to be remembered:

There is no pass-by-reference in Go.

The above is the detailed content of Go language comparison C++ reference parameter passing. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn