-2

In this snippet

    list := []string{"a", "b", "c"}
    for {
        list := repeat(list)
...

    func repeat(list []string) []string {
...

it is clear that list variable used as the argument to repeat() function is the outer, shadowed list variable. Now my question is, how would a Go language lawyer explain this behaviour? At first glance, I thought the declaration of the inner list variable would have preceded the repeat(list) expression evaluation.

Bharata
  • 13,509
  • 6
  • 36
  • 50
pajato0
  • 3,628
  • 3
  • 31
  • 37

2 Answers2

4

Go is lexically scoped using blocks. In this example:

list := []string{"a", "b", "c"}
for {
    list := repeat(list)

The second list shadows the first within the for block, and doesn't alter the outer list variable.

Because the arguments to repeat are evaluated before the inner list is declared and assigned, repeat receives the value from the outer list

JimB
  • 104,193
  • 13
  • 262
  • 255
1

It's a tough crowd on SO. The answer I was looking for was essentially that in the statement:

list := repeat(list)

the inner list variable is not in scope until the end of the statement whereas the outer list variable is in scope. Here's what the spec has to say:

Go is lexically scoped using blocks:

The scope of a predeclared identifier is the universe block. The scope of an identifier denoting a constant, type, variable, or function (but not method) declared at top level (outside any function) is the package block. The scope of the package name of an imported package is the file block of the file containing the import declaration. The scope of an identifier denoting a method receiver, function parameter, or result variable is the function body. The scope of a constant or variable identifier declared inside a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl for short variable declarations) and ends at the end of the innermost containing block. The scope of a type identifier declared inside a function begins at the identifier in the TypeSpec and ends at the end of the innermost containing block.

The highlighted text is the operational rationale that I missed in the first read. Mea culpa. :-)

pajato0
  • 3,628
  • 3
  • 31
  • 37