We've just have a discussion with a colleague about the case of what exactly variable would a function literal close over, if it calls a method on a field of a struct-typed variable available in the scope of the enclosing function.
Here's the code: -------------------------------8<-------------------------------- package main import ( "fmt" ) type Foo struct { val int } func (foo *Foo) Show() { fmt.Println(foo.val) } type Bar struct { foo *Foo } func main() { foo := &Foo{123} bar := &Bar{foo} fn := func() { bar.foo.Show() } fn() bar.foo = &Foo{456} fn() } -------------------------------8<-------------------------------- (Playground link: [1]). and the dispute was about whan variable would fn() close over. I proposed that it will close over bar.foo since it's the "narrowest" variable needed to be able to call Show(). As it turned out, I was wrong, and fn() closes over bar. My line of reasoning stems from the following passage from the spec [2]: | Structured variables of array, slice, and struct types have elements and | fields that may be addressed individually. Each such element acts like a | variable. which seem to suggest in the case above bar.foo is a variable, and since bar itself is not needed to call the Show() method provided by the bar.foo's type, the function literal would close over the field alone (presumably internally storing a pointer to it). The part of the spec which discusses function literals [3] states: | Function literals are closures: they may refer to variables defined in a | surrounding function. Those variables are then shared between the | surrounding function and the function literal, and they survive as long | as they are accessible. So there is no clearly defined rule of how the compiler decides what to capture. I've got hunch that may be [2] really has concurrent access in mind when it states "Each such element acts like a variable", and this does not apply to other cases. Can anyone please explain where there is a flaw in my line of reasoning which led me to a wrong conclusion? 1. https://play.golang.org/p/_VfdzQDNZR 2. https://golang.org/ref/spec#Variables 3. https://golang.org/ref/spec#Function_literals -- 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. For more options, visit https://groups.google.com/d/optout.