Thanks all for the insights, I think a key takeaway for me is "Don't worry about it unless it's a problem", but it's also good to know that it (probably) isn't a problem!
I'm glad at least the semantics are the same, and I guess I'll cross the performance bridge if I ever come to it and someone tries to compile my code with an alternative/older compiler. The FAQ [https://golang.org/doc/faq#pass_by_value] that raised this question for me still seems to be technically correct, but I will say the text definitely gives off a "If you're coming from C, pass big interfaces as pointers" vibe: "Map and slice values behave like pointers: they are descriptors that contain pointers to the underlying map or slice data. Copying a map or slice value doesn't copy the data it points to. Copying an interface value makes a copy of the thing stored in the interface value. If the interface value holds a struct, copying the interface value makes a copy of the struct. If the interface value holds a pointer, copying the interface value makes a copy of the pointer, but again not the data it points to." I wouldn't be surprised if other people from C/C++ fall into this trap, is there any chance the FAQ could be updated On Sunday, June 6, 2021 at 6:51:49 AM UTC+1 Amnon wrote: > I find that people coming to Go from C++ tend to use pointers everywhere > so as to avoid copying of structs. > Once they get a bit more experience, they tend to use fewer pointers, and > are happier to pass structs around. > Removing the "make everything a pointer" optimisation makes the code > simpler, and often actually makes it run faster > as fewer values escape the heap. Allocation tends to dominate Go runtime, > so it is worth doing a bit more > copying in order to get a bit less allocations. > > On Saturday, 5 June 2021 at 22:34:09 UTC+1 axel.wa...@googlemail.com > wrote: > >> I would add that because the dynamic type of an interface value is not >> known at compile time, a variable of interface type really can't (in >> general) have a specific size. >> If a function has an interface parameter, it must be possible to pass a >> value of *any* size to it. So even aside from what the current >> implementation does - any Go compiler must, in general¹, consider >> interfaces to be pretty-much-pointers. >> >> "in general" because a compiler can, of course, determine that in a >> certain scenario the value doesn't have to be packed and pass it as-is. >> This is an optimization sometimes called "devirtualization". But in the >> general case, a compiler can't prove that (e.g. the dynamic value in an >> interface could be determined by a random number generator), so it will >> always be an optimization and the default always has to be a form of boxing >> into a constantly sized shape. >> >> All of this is a good indication, from first principles, that you don't >> have to worry about the size of the dynamic value when passing it. >> >> What's more, in general you should trust the author of the package you >> are using to give you a reasonable implementation of an interface. You >> shouldn't worry what the dynamic type and value in an interface is, unless >> you have very good reason to care. In this case, unless you notice that >> your code is very slow if you don't use a pointer (that would be "a very >> good reason to care"), you shouldn't optimize it. And if you notice, you >> should open a bug against that package :) Though as established, you won't. >> >> On Sat, Jun 5, 2021 at 11:18 PM Ian Lance Taylor <ia...@golang.org> >> wrote: >> >>> On Sat, Jun 5, 2021 at 2:15 PM Joshua <joshua.o...@gmail.com> wrote: >>> > >>> > My question is general, but for ease of communicating I'll use the >>> specific example I ran into. >>> > >>> > I'm very new and for my first project I'm working with the bleve >>> library [https://pkg.go.dev/github.com/blevesearch/bleve]. >>> > >>> > One function I need, "Open", returns an interface, "Index". >>> > >>> > I'd like to write my own function to act on this interface, and given >>> that I have no idea what the dynamic value of the interface is, my first >>> instinct is to rather pass a pointer to the returned interface into my >>> function. >>> > >>> > However, I see lots of calls of "If you're using pointers to >>> interfaces a lot, you probably don't understand them". >>> > >>> > Well, what am I not understanding? >>> > My worry is that I have no idea what dynamic type is lurking within >>> the interface, if it's a pointer to a struct, then I obviously don't mind >>> passing it into my function. >>> > >>> > However if it is in fact a humungous 1GB struct, then I really really >>> don't want to be copying that around willy-nilly. >>> > >>> > Is there a way in general to avoid this, without looking at the >>> library source code to see what the actual concrete type is? >>> >>> In the current implementations a value of interface type is always a >>> pair of pointers. Even if the value of interface type happens to >>> refer to a 1GB struct, copying the interface value, including passing >>> it to a function or returning it from a function, always just copies >>> two pointers. >>> >>> Ian >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "golang-nuts" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to golang-nuts...@googlegroups.com. >>> To view this discussion on the web visit >>> https://groups.google.com/d/msgid/golang-nuts/CAOyqgcUuv_qrrG8%3DdCQZv0%2BrKbnbW60XdOCwjp8M3EdOCxCNkw%40mail.gmail.com >>> . >>> >> -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/a891bbf5-9426-49b3-89c6-f185fe047b5en%40googlegroups.com.