Переменное затенение - Variable shadowing
В компьютерном программировании , переменная затенение происходит , когда переменная объявлена в пределах определенного объема (решение блока, методы или внутреннего класса ) имеет такое же имя , как переменная объявлена во внешней области видимости. На уровне идентификаторов (имен, а не переменных) это называется маскированием имени . Говорят, что эта внешняя переменная затенена внутренней переменной, в то время как внутренний идентификатор, как говорят, маскирует внешний идентификатор. Это может привести к путанице, поскольку может быть неясно, к какой переменной относятся последующие использования имени скрытой переменной, что зависит от правил разрешения имен языка.
Одним из первых языков, в которых было введено затенение переменных, был ALGOL , в котором впервые были введены блоки для определения областей видимости. Это также было разрешено многими производными языками программирования, включая C , C ++ и Java .
Язык C # нарушает эту традицию, разрешая затенение переменных между внутренним и внешним классами, а также между методом и содержащим его классом, но не между блоком if и содержащим его методом или между операторами case в блоке switch .
Некоторые языки допускают затенение переменных в большем количестве случаев, чем другие. Например, Kotlin позволяет внутренней переменной в функции затенять переданный аргумент, а переменная во внутреннем блоке затенять другую во внешнем блоке, в то время как Java не позволяет этого. Оба языка позволяют переданному аргументу функции / методу затенять поле класса.
Некоторые языки полностью запрещают затенение переменных, например CoffeeScript .
Пример
Lua
Следующий код Lua предоставляет пример затенения переменных в нескольких блоках.
v = 1 -- a global variable
do
local v = v + 1 -- a new local that shadows global v
print(v) -- prints 2
do
local v = v * 2 -- another local that shadows outer local v
print(v) -- prints 4
end
print(v) -- prints 2
end
print(v) -- prints 1
Python
Следующий код Python предоставляет еще один пример затенения переменных:
x = 0
def outer():
x = 1
def inner():
x = 2
print("inner:", x)
inner()
print("outer:", x)
outer()
print("global:", x)
# prints
# inner: 2
# outer: 1
# global: 0
Поскольку в Python нет объявления переменных, а только присваивается переменная, ключевое слово, nonlocalвведенное в Python 3, используется для предотвращения затенения переменных и назначения нелокальным переменным:
x = 0
def outer():
x = 1
def inner():
nonlocal x
x = 2
print("inner:", x)
inner()
print("outer:", x)
outer()
print("global:", x)
# prints
# inner: 2
# outer: 2
# global: 0
Ключевое слово globalиспользуется, чтобы избежать затенения переменных и присвоить глобальным переменным:
x = 0
def outer():
x = 1
def inner():
global x
x = 2
print("inner:", x)
inner()
print("outer:", x)
outer()
print("global:", x)
# prints
# inner: 2
# outer: 1
# global: 2
Ржавчина
fn main() {
let x = 0;
{
let x = 1;
println!("Inner x: {}", x); // prints 1
}
println!("Outer x: {}", x); // prints 0
// Shadow
let x = "Rust";
println!("Outer x: {}", x); // prints 'Rust'
}
//# Inner x: 1
//# Outer x: 0
//# Outer x: Rust
C ++
#include <iostream>
int main()
{
int x = 42;
int sum = 0;
for (int i = 0; i < 10; i++) {
int x = i;
std::cout << "x: " << x << '\n'; // prints values of i from 0 to 9
sum += x;
}
std::cout << "sum: " << sum << '\n';
std::cout << "x: " << x << '\n'; // prints out 42
return 0;
}
Джава
public class Shadow {
private int myIntVar = 0;
public void shadowTheVar() {
// Since it has the same name as above object instance field, it shadows above
// field inside this method.
int myIntVar = 5;
// If we simply refer to 'myIntVar' the one of this method is found
// (shadowing a second one with the same name)
System.out.println(myIntVar); // prints 5
// If we want to refer to the shadowed myIntVar from this class we need to
// refer to it like this:
System.out.println(this.myIntVar); // prints 0
}
public static void main(String[] args){
new Shadow().shadowTheVar();
}
}
JavaScript
Введение в ECMAScript 6 `let` и` const` с блочной областью видимости допускает затенение переменных.
function myFunc() {
let my_var = 'test';
if (true) {
let my_var = 'new test';
console.log(my_var); // new test
}
console.log(my_var); // test
}
myFunc();
Смотрите также
использованная литература
- ^ "Архивная копия" . Архивировано 28 ноября 2020 года . Проверено 2021-10-04 .CS1 maint: заархивированная копия как заголовок ( ссылка )
- ^ "Архивная копия" . Архивировано 4 октября 2021 года . Проверено 2021-10-04 .CS1 maint: заархивированная копия как заголовок ( ссылка )