Copy reference to pointer or value

I think I understand the answer from here , but just in case, I want to explicitly ask about the following (my apologies if you think this is the same question, but for me it depends on the problems):

func f() *int { d := 6 pD := new(int) pD = &d // option 1 *pD = d // option 2 return pD } 

The first option, when I just copy the link as a pointer, has a performance that is more optimal (this is an educational assumption, but it seems obvious). I would prefer this method / template.

The second option (shallow) copies (?). I believe this method, because it copies, I am not worried that the GC sweeps the instance of 'd'. I often use this method because of my uncertainty (or ignorance as a newbie).

What bothers me (or, moreover, is unsafe) is that in the first method (where the address "d" is passed) the GC recognizes that it (the variable "d") is referenced by the container pointer, so it does not will be swept away? So will it be safe to use this method instead? That is, can I safely pass the pointer 'pD' returned from func 'f ()' for the application lifetime?

Link: https://play.golang.org/p/JWNf5yRd_B

+7
go
source share
2 answers

There is no better place to view than the official documentation:

 func NewFile(fd int, name string) *File { if fd < 0 { return nil } f := File{fd, name, nil, 0} return &f } 

Note that, unlike C ,, it is quite normal to return the address of a local variable; the memory associated with the variable is saved after the function returns. In fact, assuming the address of a compound literal allocates a new instance each time it is evaluated, so we can concatenate these last two lines.

(source: Effective Transition )

Thus, the first option (returning a pointer to a local variable) is absolutely safe and even encouraged. When performing a leak analysis , the compiler can say that the variable goes beyond its local scope and instead allocates it to the heap.

+9
source share

In short: None.

First: Go has no "links." Forget about this idea now, otherwise you will hurt yourself. Indeed. Thinking about "by reference" is simply wrong.

Second: performance is exactly the same. Forget about this kind of nano optimization now. Especially when working with int. If and only if you have a performance problem: Measure and then optimize. Perhaps it would be intuitively appealing to think: "Manual operation with a tiny pointer of 8 bytes should be much faster than copying structures with 30 or even 100 bytes." This is not so, at least it is not so simple.

Third: just write it func f() *int { d := 6; return &d; } func f() *int { d := 6; return &d; } func f() *int { d := 6; return &d; } . There is no need to do any fantastic dances.

Fourth: Option 2 makes a deep copy of int. But this can be misleading since there are no โ€œsmall copiesโ€ for int, so I'm not sure if I understand what you are asking here. Go has no concept of deep and shallow copy. If you copy the pointer value, the pointer value will be copied. Do you remember the first point? There are no links in Go. The pointer value is the value, if it is copied, you have a copy of the pointer value. Such a copy does nothing for the value it points to, especially it does not make a copy. This suggests that the copies in Go are not deep. Forget about deep / shallow copy when talking about Go. (Of course, you can implement functions that perform a โ€œdeep copyโ€ of your custom objects)

Fifth: Go has a properly working garbage collector. It does not matter what you do: as long as the object is alive, it will not be assembled, and once it is assembled, it will be. You can send, return, copy, transmit, receive address, dereference pointers, or whatever you like, it just doesn't matter. GC is working correctly. (If you are not intentionally looking for pain and errors, use an unsafe package.)

+3
source share

All Articles