I'm new to learning Go, and so far I find that a common "itch" is deciding whether to use a value or pointer receiver for a method on a struct. The Go FAQs (https://golang.org/doc/faq#methods_on_values_or_pointers) state that for large structs, using a value receiver can be inefficient. I am wondering if in some situations the Go compiler can spot inefficient value receivers and optimize to a pointer function under-the-hood, and if it does not do so currently if such an optimization would be feasible?
To me, value receivers seem like a good way of showing that a method does not mutate the struct it is called on, since Go has no other way of marking const methods that I can see. But it would be a drawback if value receivers are often inefficient.
In a language like C/C++ it is left to the programmer to know to use a const pointer or reference respectively for functions/methods that take large structs. My impression of Go is that the language is much simplified (over C++ at least) to make life easier for the developer, and to balance this language simplification the compiler makes a lot more optimization decisions on behalf of the programmer (e.g. deciding if a variable is allocated on the stack or heap).
I'm aware that the Go compiler can inline functions, however not in the presence of many common constructs e.g. loops, panics or switch. What I would like here is not for the function to be inlined, but for it to be implicitly converted to the efficient pointer receiver implementation.
A trivial example involving a struct that implements a stack, along with some other data that we assume is expensive to copy:
type Foo struct {
stackData []int
stackDataIx int
// assume many other attributes on this struct that make it expensive to copy
...
}
// Could the compiler optimize this to a pointer receiver? foo is not mutated.
func (foo Foo) Peek() int {
if foo.stackDataIx < 0 {
panic("Stack is empty")
}
return foo.stackData[foo.stackDataIx]
}
The code works, but is less efficient than the pointer version. I have yet run any benchmarks, this is more of a theoretical question.