Lexical Scope

What is Lexical Scope in Go ?

What doesHeamorrage lexical scope mean? To simply answer this, it means that it contains the reference to the parent environment/surrounding state.

For example: In the case below, what would be the output?

package main

import (
	"fmt"
)

func main() {
 	var a int = 1
	fmt.Print(a)
}

// Output
// 1

The output was as expected right? What if we didnt have variable a in main function? For example:


package main

import (
	"fmt"
)

var a string = "hello"

func main() {
	fmt.Print(a)
}

// Output
// hello

What happens here is that it did not find a in the scope of function main so it went one level up to the parent and checked for global variable with name a and outputs its value as hello

What happens if we keep both the variables (at global and function level)? what would be the output in that case?

package main

import (
	"fmt"
)

var a string = "hello"

func main() {

	var a int = 1
	fmt.Print(a)
}

// Output
// 1

The language takes the function level variable a and prints its value

Lets take an another example. What do you think would be the password

package main

import (
	"fmt"
)

var a string = "hello"

func main() {

	var a int = 1
	fmt.Println(a)
	fmt.Println(b)
}

var b string = "world"

// Output
// 1
// world

Here we define the variable b after the main function but we access it before it is declared and intialized.We see even if it is declared later, we are still able to access it

Note: We cannot have non-declaration statement outside the function What this means is we cannot have declarations like x:= 1 at the global scope level

To see this point let’s take an example,


package main

import (
	"fmt"
)

var a string = "hello"

var b string = "hi"

func main() {
	fmt.Println(b)
}

b = "world" // this line throws an error

// output
// syntax error: non-declaration statement outside function body

Why did we get an error? As mentioned in the error, we cannot have non-declaration statement(ie. statements where are just assigning values).

Can you guess the output of the code snippet below


package main

import (
	"fmt"
)

func main() {

	var x int = 1
	y := 1	
	
	if true {
		x := 2
		y = 2
		fmt.Println(x)
		fmt.Println(y)
	}
	
	fmt.Println(x)
	fmt.Println(y)
}

Output
2
2
1
2

What happenend here ? The if block creates a new variable x whose scope is limited to that if block only and hence value of x is 2 inside the block and outside the block the x references to the x with value 1.

For y, it could not find any variable in the scope of if condition. So it updates the value of y in the outer scope.

Food for thought If you are familiar with javascript, then must have already known this concept. However there is one thing that I found Golang does not support hoisting whereas javascript does. Feel free to explore more.

Try out these examples in the playground for yourself

Read more about Declarations and Scope in the official documentation

Do let me know your thoughts via mail

Updated: