How to store function scope when using function literals in goroutine?

267 views
Skip to first unread message

Jean de Klerk

unread,
Jun 5, 2014, 11:49:36 PM6/5/14
to golan...@googlegroups.com
I started playing with simple goroutines using function literals recently, and I found that inside the function literal I could use variables from the function my literal is defined in. See the following: http://play.golang.org/p/i6i3dcoZ2U.

However, I can also pass in a variable from the parent: http://play.golang.org/p/AJyPGG9I3W.

So, this begs the question: if my function literal local variable is named the same as a variable in my "parent" function, how can I access the "parent" variable?

If this isn't clear: in javascript we sometimes save scope with something like var self = this;. In php and java, we can do things like super and parent. Does go have something like this?

TL;DR: How would I get something like http://play.golang.org/p/AJyPGG9I3W to output "bar"?

Thanks for any help,
Jean

Dan Kortschak

unread,
Jun 5, 2014, 11:52:27 PM6/5/14
to Jean de Klerk, golan...@googlegroups.com
On Thu, 2014-06-05 at 20:49 -0700, Jean de Klerk wrote:
> TL;DR: How would I get something like
> http://play.golang.org/p/AJyPGG9I3W
> to output "bar"?
>
Don't use the name foo for the parameter?

Jean de Klerk

unread,
Jun 5, 2014, 11:58:10 PM6/5/14
to golan...@googlegroups.com, jade...@gmail.com
Well, yes... But the point of the question is not about programming style, it's about learning more about Go. :)

And, for the record, here is perhaps a better example showing that the goroutine uses a (presumedly) pass-by-value when we hand it a variable, as opposed to using the "parent" function when we give it no variable: http://play.golang.org/p/PpqIpl38AJ.

If it can do both depending on whether or not you give it the variable, does it not make sense that there would be some kind of tool (again, like parent or self or super) to manually look up the chain instead of using the most locally defined?

Jean

DV

unread,
Jun 6, 2014, 12:02:18 AM6/6/14
to golan...@googlegroups.com, jade...@gmail.com
This is so very confusing to me. I'm probably not doing what you want either, but:


I'm not even sure how that's different from Javascript, honestly. Why not just name the outer variable something different? Is it different from any other language with similar scoping rules? I must be missing something. 

Jesse McNelis

unread,
Jun 6, 2014, 12:07:11 AM6/6/14
to Jean de Klerk, golang-nuts
On Fri, Jun 6, 2014 at 1:58 PM, Jean de Klerk <jade...@gmail.com> wrote:
> Well, yes... But the point of the question is not about programming style,
> it's about learning more about Go. :)
>
> And, for the record, here is perhaps a better example showing that the
> goroutine uses a (presumedly) pass-by-value when we hand it a variable, as
> opposed to using the "parent" function when we give it no variable:
> http://play.golang.org/p/PpqIpl38AJ.
>
> If it can do both depending on whether or not you give it the variable, does
> it not make sense that there would be some kind of tool (again, like parent
> or self or super) to manually look up the chain instead of using the most
> locally defined?

The scoping rules for Go are really simple.
http://golang.org/ref/spec#Declarations_and_scope
There is no way to access a variable not currently in scope,
this includes variables of the same named declared in an outer scope
and shadowed in an inner scope.

I'm not sure if you're asking the right question.
Are you actually wanting a pointer to the value? like this?
http://play.golang.org/p/A_wIvJu5kS

or perhaps just close over that variable?
http://play.golang.org/p/aZs39SMrXa

Jean de Klerk

unread,
Jun 6, 2014, 12:19:17 AM6/6/14
to golan...@googlegroups.com, jade...@gmail.com, jes...@jessta.id.au
Sorry, didn't hit reply all. To sum:

Hi Dimiter,

Here is a jsfiddle of how javascript would solve this problem: http://jsfiddle.net/Hha9z/. Note that it can store the scope of the "parent" function in a variable and use that to access the "parent" foo later. Again, in languages like php and java (for reference to the fact that more than just javascript can do this) we would use parent or super.

Jesse,

Nope to the pointers question, I want to be able to access both the local and the parent scoped foo. I guess I could pass in a pointer and the value, but that's not really the issue.

Thanks for the links about scope - I'm still reading through it but it seems that perhaps Go cannot do this scope switching.

chris dollin

unread,
Jun 6, 2014, 12:25:26 AM6/6/14
to Jean de Klerk, golang-nuts, Jessta
On 6 June 2014 05:19, Jean de Klerk <jade...@gmail.com> wrote:

Thanks for the links about scope - I'm still reading through it but it seems that perhaps Go cannot do this scope switching.

It has no machinery for "scope switching" and in the examples you
show no need for it, since renaming a few variables makes them
accessible using the traditional nested scope rules.

Chris

--
Chris "allusive" Dollin

Jean de Klerk

unread,
Jun 6, 2014, 12:31:57 AM6/6/14
to golan...@googlegroups.com
Ah ok, thanks! It was indeed just a question of ability to do something you can in another language, versus a question about best practices. =)

Thanks again,
Jean

Jesse McNelis

unread,
Jun 6, 2014, 12:34:28 AM6/6/14
to Jean de Klerk, golang-nuts
On Fri, Jun 6, 2014 at 2:31 PM, Jean de Klerk <jade...@gmail.com> wrote:
> Ah ok, thanks! It was indeed just a question of ability to do something you
> can in another language, versus a question about best practices. =)
>

I've never seen 'scope switching' like that in any language.

akwi...@gmail.com

unread,
Jun 6, 2014, 4:10:38 PM6/6/14
to golan...@googlegroups.com
I think your issue has to do with variable shadowing.The best option would be to use different variables names, but you could encapsulate the variable in a struct like so:

Daniel Theophanes

unread,
Jun 6, 2014, 5:22:07 PM6/6/14
to golan...@googlegroups.com, jade...@gmail.com, jes...@jessta.id.au
And here is the solution in Go:

Use a struct.

-Daniel

Jean de Klerk

unread,
Jun 6, 2014, 5:31:01 PM6/6/14
to golan...@googlegroups.com, akwi...@gmail.com
Very cool - thanks! That is something I would not have thought of doing.

Thanks again,
Jean
Reply all
Reply to author
Forward
Message has been deleted
0 new messages