Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Whether there is reference passing in function parameter passing in Golang

2025-02-22 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/01 Report--

Today, I will talk to you about whether there is reference transfer for function parameters in Golang. Many people may not know much about it. In order to make you understand better, the editor has summarized the following content for you. I hope you can get something according to this article.

There is only one way for functions to pass parameters in Go.

Value transfer

Value passing means that a copy of the actual parameter is passed to the function when the function is called, so that if the parameter is modified in the function, the actual parameter will not be affected.

Concepts always give people the feeling of a textbook, write some code to verify.

Func main () {a: = 10 fmt.Printf ("% # v\ n", & a) / (* int) (0xc420018080) vFoo (a)}

Func vFoo (b int) {fmt.Printf ("% # v\ n", & b) / (* int) (0xc420018090)

}

The comment content is the output of my machine, if you run it, you will get a different output.

According to the code, the so-called value transfer is: after the argument an is passed to the parameter b of the function vFoo, inside the vFoo, b will be used as a local variable to allocate space on the stack and completely copy the value of a.

After the code is executed, we see that an and b have completely different memory addresses, indicating that although they have the same value (b copies a, the value must be the same), they are different in memory, so if you change the value of b inside the function vFoo, a will not be affected.

On the left side of the figure is the allocation of memory before it is called, and on the right is the variables allocated to memory after the function is called. It should be noted here that even if the parameter name of vFoo is a, the actual participating parameter also has its own memory space, because the name of the parameter is only for programmers, which was made clear in the previous article.

Pointer transmission

A formal parameter is a pointer to the address of the argument, and when pointing to the parameter, it is equivalent to the operation on the argument itself.

Is it in the clouds? Or analyze the so-called pointer passing through code combination.

Func main () {a: = 10 pa: = & a fmt.Printf ("value:% # v\ n", pa) / / value: (* int) (0xc420080008) fmt.Printf ("addr:% # v\ n", & pa) / / addr: (* * int) (0xc420088018) pFoo (pa)}

Func pFoo (p * int) {fmt.Printf ("value:% # v\ n", p) / value: (* int) (0xc420080008) fmt.Printf ("addr:% # v\ n", & p) / / addr: (* * int) (0xc420088028)

}

A variable an is defined and the address is stored in the pointer variable pa. According to our conclusion, only the value is passed in the Go, then after the pointer variable pa is passed to the function parameter p, the parameter will be a copy of it on the stack, and they will have different addresses, but the values of the two are the same (both are the address of the variable a). The comments above are the result of the running of my program. The addresses of pa and p are not related to each other, indicating that a value copy occurred in the parameter transfer.

In the function pFoo, the address of parameter p is not the same as that of the argument pa, but their values in memory are the address of the variable a, so the value of a can be changed through pointer-related operations.

In the figure, & a represents the address of a, and the value is: 0xc420080008

Reference transfer

The so-called reference passing means that the address of the actual parameter is passed to the function when the function is called, then the modification of the parameter in the function will affect the actual parameter.

Since there is no reference passing in Go, we often see that reference passing in Go is also aimed at: Slice, Map, and Channel (this is a wrong point of view), so in order to explain reference passing clearly, let's first take a look at a piece of C++ code (very simple, of course).

Void rFoo (int & ref) {

Printf ("% p\ n", & ref); / / 0x7ffee5aef768

}

Int main () {

Int a = 10

Printf ("% p\ n", & a); / / 0x7ffee7307768 int & b = a

Printf ("% p\ n", & b); / / 0x7ffee5aef768 rFoo (b)

Return 0;}

This is simply defining a reference in main and passing it to the function rFoo, so let's see what orthodox reference passing looks like.

Here b is an alias for a (quote, if not clear, please see my previous article), so an and b must have the same address. Then, according to the definition passed by reference, after argument b is passed to parameter ref, ref will be an alias for b (that is, a, b, and ref are all the same variable), and they will have the same address. By printing the information in the rFoo function, you can see that the three have exactly the same address, which is called reference passing.

There is no reference passing in Go

Function calls in Go can only pass values, but type references have reference types, which are: slice, map, channel. Let's take a look at the official saying:

There's a lot of history on that topic. Early on, maps and channels were syntactically pointers and it was impossible to declare or use a non-pointer instance. Also, we struggled with how arrays should work. Eventually we decided that the strict separation of pointers and values made the language harder to use. Changing these types to act as references to the associated, shared data structures resolved these issues. This change added some regrettable complexity to the language but had a large effect on usability: Go became a more productive, comfortable language when it was introduced.

It started with pointer syntax and changed to a reference for a variety of reasons, but this reference is different from the C++ reference, it is a structure that shares associated data. I'll put an in-depth discussion on this issue in an slice-related article, and now go back to the topic of today's discussion.

So where does the reference transfer of Go come from? I think what makes you misunderstand is the misunderstanding caused by the reference types such as map, slice and channel that can be modified inside the function when they are passed to the function.

We use slice to verify that these three types are by value delivery.

Func main () {arr: = [5] int {1,3,5,6,7} fmt.Printf ("addr:%p\ n", & arr) / / addr:0xc42001a1e0 S1: = arr [:] fmt.Printf ("addr:%p\ n", & S1) / / addr:0xc42000a060 changeSlice (S1)}

Func changeSlice (s [] int) {fmt.Printf ("addr:%p\ n", & s) / / addr:0xc42000a080 fmt.Printf ("addr:%p\ n", & s [0]) / / addr:0xc42001a1e0

}

An array arr is defined in the code and then used to generate a slice. If there is reference passing in go, the address of formal parameter s should be the same as that of actual reference S1 (as proved by C++ above). Through the actual situation, we find that they have completely different addresses, that is, the passing of parameters still occurs copy-value transfer.

But there is a strange phenomenon here, you can see that the address of arr and s [0] have the same address, which is why we can modify slice inside the function, because when it is passed into the function as a parameter, slice itself is a copy of the value, but it internally references the structure of the corresponding array, so s [0] is the reference of arr [0], which is why it can be modified.

There is only one way for function parameters to be passed in Go.

Slice, map and channel are all reference types, but they are different from C++ 's.

Slice can modify the corresponding array value after passing parameters through the function because the pointer to the reference array is kept inside the slice, not because the reference is passed.

After reading the above, do you have any further understanding of whether there is reference passing in function parameter passing in Golang? If you want to know more knowledge or related content, please follow the industry information channel, thank you for your support.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report