Переменное затенение
В программировании компьютерном затенение переменных происходит, когда переменная, объявленная в определенной области (блоке принятия решений, методе или внутреннем классе ), имеет то же имя, что и переменная, объявленная во внешней области. На уровне идентификаторов (имен, а не переменных) это называется маскированием имени . Говорят, что эта внешняя переменная затенена внутренней переменной, тогда как внутренний идентификатор маскирует внешний идентификатор. Это может привести к путанице, поскольку может быть неясно, к какой переменной относятся последующие использования имени затененной переменной, что зависит от правил разрешения имен языка.
Одним из первых языков, в котором было реализовано затенение переменных, был ALGOL , в котором впервые были введены блоки для установления областей видимости. Это также было разрешено многими производными языками программирования, включая C , C++ и Java .
Язык C# нарушает эту традицию, допуская затенение переменных между внутренним и внешним классом, а также между методом и содержащим его классом, но не между блоком if и содержащим его методом или между операторами case в блоке переключателя .
Некоторые языки допускают затенение переменных в большем количестве случаев, чем другие. Например, Kotlin позволяет внутренней переменной в функции скрывать переданный аргумент, а переменная во внутреннем блоке — скрывать другую во внешнем блоке, тогда как Java этого не позволяет. Оба языка позволяют передавать аргумент функции/методу для скрытия поля класса. [1]
Некоторые языки полностью запрещают затенение переменных, например CoffeeScript . [2]
Пример [ править ]
Луа [ править ]
Следующий код 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 представляет собой еще один пример затенения переменных:
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;
{
// Shadow
let x = 1;
println!("Inner x: {}", x); // prints 1
}
println!("Outer x: {}", x); // prints 0
let x = "Rust";
println!("Outer x: {}", x); // prints 'Rust'
}
//# Inner x: 1
//# Outer x: 0
//# Outer x: Rust
С++ [ править ]
#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();
См. также [ править ]
Ссылки [ править ]
- ^ «От Java к Котлину и обратно» . Архивировано из оригинала 28 ноября 2020 г. Проверено 4 октября 2021 г.
- ^ «Пожалуйста, введите явное затенение · Проблема № 2697 · jashkenas/Coffeescript» . Гитхаб . Архивировано из оригинала 04 октября 2021 г. Проверено 4 октября 2021 г.