Будет ли Go делать копию моей структуры, если я верну по значению вместо указателя? - PullRequest
0 голосов
/ 30 сентября 2019

Взять этот пример:

type Foo struct {
    num int
}

// func NewFoo() *Foo { // returning a pointer
//     return &Foo{33}
// }

func NewFoo() Foo { // NOT returning a pointer
    return Foo{33}
}

func main() {
    fff := NewFoo()
    fmt.Printf("%d\n", fff.num)
}

Если NewFoo возвращает указатель, я понимаю, что объект хранится в куче, а fff получает указатель на тот же объект, выделенный в куче.

Теперь со второй реализацией NewFoo, которая не будет возвращать указатель, Go вернет копию структуры, размещенной в стеке, или что-то вроде C ++ 'RVO происходит?

1 Ответ

0 голосов
/ 01 октября 2019

Вы можете проверить это, выполнив следующие действия:

  1. Напишите вашу программу в файле, скажем main.go, например: https://play.golang.org/p/iwxai0EHa40

  2. Выполнитькоманда go build -gcflags=-m main.go

  3. См. вывод, чтобы действительно знать, копируется ли он / вставляется. В моем случае вывод, который я получаю:

# command-line-arguments
./main.go:13:6: can inline NewFoo
./main.go:17:6: can inline main
./main.go:18:15: inlining call to NewFoo
./main.go:19:12: inlining call to fmt.Printf
./main.go:19:24: fff.num escapes to heap
./main.go:19:12: io.Writer(os.Stdout) escapes to heap
./main.go:19:12: main []interface {} literal does not escape
<autogenerated>:1: os.(*File).close .this does not escape

Эту процедуру вы можете выполнить в любой программе Go, чтобы проверить, не происходит ли в вашей программе ненужное выделение кучи, которого вы можете избежать. ,

Вот небольшая статья , в которой рассматриваются различные способы повышения эффективности вашей программы.

...