Variable Shadowing in “Go”
What is Variable Shadowing and why should you learn it?
Before you dive into it and end up confusing yourself, let’s look at what variable scope means. Variable scope refers to the visibility of the variable in the region of the program. Eg:
In this example, the variable lastName is only accessible inside main function as it’s been declared inside main (locally). Whereas the variable firstName can be accessed anywhere in the file because it’s been declared at the top of file, outside of all the functions (globally). That’s why, greeting and main, both the functions can access firstName.
Now, let’s look at Variable Shadowing.
A variable is said to be shadowing another variable if it “overrides” the variable in a more specific scope.
In this example, the global variable (Line 1) and the variable in the if block (Line 4) have same name i.e. number. You may think, when the number > 0 then both the print statements should print the same value. However, the outside if print statement always prints “0” because of variable shadowing.
So if you redeclare a variable in the inner block (i.e. main function), it’s a new variable with the same name as in the outer block. Any changes in this new variable won’t affect the outer block variable.
Real life use case
Requirement: Convert any type of valid data into map.
To achieve that I created a function that accepts data as an interface and returns two values- a map and an error.
If there is an error while marshalling or unmarshalling, it will be assigned to err variable (declared in Line 1). Otherwise result will be assigned in j.
I tested it and.…it did not work with faulty data (Thanks to unit testing 😅).
Why don’t you take a minute and see what’s wrong in the function.
If you have figured it out. Great!!!. Otherwise let me explain.
In this example, the return err variable (Line 1) and err in if block (Line 4) have same name. The second err variable (Line 4) is a new variable and has its scope only in if block. Any changes in the err inside if block won’t have any effect on the return err variable.
So, I broke down the if statement and removed the := (short hand declaration).
It worked!!! as expected.
These kind of silent errors won’t get picked up by compiler and it can cause errors. So, be careful about variable shadowing and always unit test your code 😅 .
You can read more about declaration and scope in Golang specifications doc.