I just ran into an issue with a closure inside a function that I originally
created elsewhere with the same names as where I transplanted the closure
definition, and it took me quite some time to root out all the references
to the outer scope.
Scope bleed and shadowing with closures is something that should be
emphasised as an issue when dealing with closures, especially when it
involves context variables.
I found a way to exploit the scoping rules to rapidly highlight all the
incorrectly unchanged references to outer scope context by creating an
inner scope declaration of a variable of a different type with the name of
this overlapping outer scope, in this case an int. Then instantly all the
references inside the closure referring to this outer name have been
changed to be int type and become type/member errors.
Unfortunately I didn't figure it out until I had just finally nabbed the
last one, but hopefully I will remember it for future and that maybe it
helps someone else who uses closures a lot in Go.
The code is inside a configuration menu system I am writing and it uses
closures to attach handlers to objects.
I have learned two important scoping rules that goes beyond just closures
in the process;
1. It is possible to declare a name inside a block same as outside the
block with no limitations (thus using the outer name to zap incorrect
lingering references inside a closure).
2. For variables are not multiply declared - inside a closure a reference
to variables declared using := in a for statement are a single variable and
usually means the closure has only the last value in the iteration in its
references to these values. You have to declare a new variable inside the
for statement to ensure it pins to the specific instance of the loop and
the state at that time.
I also observed a while ago and it can be annoying sometimes (and sometimes
actually there is no better way to express) than an if/else if/else
construction, one has to be aware in that case that the if{}else{}else{} is
a contiguous scope block and all names declared either in the optional if
statement or inside the blocks can be seen by the others. I think this
visibility is progressive, ie you can't see the variable declared in the
next else if{} block, only the ones beforehand.
--
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 [email protected].
For more options, visit https://groups.google.com/d/optout.