I just started with GoLang. I have noticed there are some initializations like this
agentUi := &f.Foo{
Reader: os.Stdin,
Writer: os.Stdout,
ErrorWriter: os.Stderr,
}
Coming from a c background , I am under the impression the reason above was done because the developer wanted to create a pointer agentUi instead of an object where he could have done something like this
agentUi := f.Foo{
Reader: os.Stdin,
Writer: os.Stdout,
ErrorWriter: os.Stderr,
}
so basically making sure that the object is still valid after the scope ends.In short create the object on the heap instead of the stack. Is that correct ?
CodePudding user response:
The pointer remains valid after the scope ends.
Heap/stack does that concept exist?
The concept is not part of the language specification. The specification does not use the term heap or stack.
In short create the object on the heap instead of the stack.
It's possible that the object is allocated on the heap, but it's also possible that the compiler optimized the allocation to the stack.
CodePudding user response:
Go does not allow direct control over where the memory you use is allocated.
If you aren't using references, the memory is allocated from the stack.
If you are passing references around, the compiler does escape analysis in order to try to allocate from the stack, but failing that, the memory is allocated on the heap.
You can use -gcflags '-m -l'
to see escape analysis for your program.
go run -gcflags '-m -l' main.go
For instance, verifying escape analisys on the program below.
package main
import (
"fmt"
"io"
"os"
)
func main() {
fmt.Printf("%v\n", work())
}
type Foo struct {
Reader io.Reader
Writer io.Writer
ErrorWriter io.Writer
}
func work() *Foo {
agentUi := &Foo{
Reader: os.Stdin,
Writer: os.Stdout,
ErrorWriter: os.Stderr,
}
return agentUi
}
Output:
$ go run -gcflags '-m -l' main.go
# command-line-arguments
./main.go:20:13: &Foo{...} escapes to heap
./main.go:10:12: ... argument does not escape
&{0xc00000e010 0xc00000e018 0xc00000e020}