Variable shadowing
In computer programming, variable shadowing occurs when a variable declared within a certain scope has the same name as a variable declared in an outer scope. At the level of identifiers, this is known as name masking. This outer variable is said to be shadowed by the inner variable, while the inner identifier is said to mask the outer identifier. This can lead to confusion, as it may be unclear which variable subsequent uses of the shadowed variable name refer to, which depends on the name resolution rules of the language.
One of the first languages to introduce variable shadowing was ALGOL, which first introduced blocks to establish scopes. It was also permitted by many of the derivative programming languages including C, C++ and Java.
The C# language breaks this tradition, allowing variable shadowing between an inner and an outer class, and between a method and its containing class, but not between an if-block and its containing method, or between case statements in a switch block.
Some languages allow variable shadowing in more cases than others. For example Kotlin allows an inner variable in a function to shadow a passed argument and a variable in an inner block to shadow another in an outer block, while Java does not allow these. Both languages allow a passed argument to a function/Method to shadow a Class Field.
Some languages disallow variable shadowing completely such as CoffeeScript and V (Vlang).
Example
Lua
The following Lua code provides an example of variable shadowing, in multiple blocks.v = 1 -- a global variable
do
local v = v + 1 -- a new local that shadows global v
print -- prints 2
do
local v = v * 2 -- another local that shadows outer local v
print -- prints 4
end
print -- prints 2
end
print -- prints 1
Python
The following Python code provides another example of variable shadowing:x = 0
def outer:
x = 1
def inner:
x = 2
inner
outer
- prints
- inner: 2
- outer: 1
- global: 0
As there is no variable declaration but only variable assignment in Python, the keyword
nonlocal introduced in Python 3 is used to avoid variable shadowing and assign to non-local variables:x = 0
def outer:
x = 1
def inner:
nonlocal x
x = 2
inner
outer
- prints
- inner: 2
- outer: 2
- global: 0
The keyword
global is used to avoid variable shadowing and assign to global variables:x = 0
def outer:
x = 1
def inner:
global x
x = 2
inner
outer
- prints
- inner: 2
- outer: 1
- global: 2
Rust
fn main
//# Inner x: 1
//# Outer x: 0
//# Outer x: Rust
C++
- include
Java
public class Shadow
However, the following code will not compile:
public class Shadow
JavaScript
ECMAScript 6 introduction oflet and const with block scoping allow variable shadowing.function myFunc
myFunc;