Переменное затенение - Variable shadowing
В компьютерное программирование, переменное затенение происходит, когда переменная объявлена в определенном объем (блок решения, метод или внутренний класс) имеет то же имя, что и переменная, объявленная во внешней области. На уровне идентификаторов (имен, а не переменных) это известно как маскировка имени. Говорят, что эта внешняя переменная затенена внутренней переменной, в то время как внутренний идентификатор называется маска внешний идентификатор. Это может привести к путанице, так как может быть неясно, к какой переменной относятся последующие использования имени скрытой переменной, что зависит от разрешение имени правила языка.
Одним из первых языков, в которых было введено затенение переменных, был АЛГОЛ, который первым ввел блоки для определения объемов. Это также было разрешено многими производными языками программирования, включая C, C ++ и Ява.
В C # язык нарушает эту традицию, разрешая затенение переменных между внутренним и внешним классом, а также между методом и содержащим его классом, но не между блоком if и содержащим его методом или между операторами case в переключатель блок.
Некоторые языки допускают затенение переменных в большем количестве случаев, чем другие. Например Котлин разрешить внутренней переменной в функции затенять переданный аргумент, а переменной во внутреннем блоке затенять другую во внешнем блоке, в то время как Ява не допускает этого. Оба языка позволяют переданному аргументу функции / методу затенять поле класса.[1]
Некоторые языки полностью запрещают затенение переменных, например CoffeeScript.[2]
пример
Lua
Следующее Lua код предоставляет пример затенения переменных в нескольких блоках.
v = 1 - глобальная переменнаяделать местный v = v + 1 - новый локальный объект, который затеняет глобальный v Распечатать(v) - оттиски 2 делать местный v = v * 2 - еще один локальный объект, который затеняет внешний локальный v Распечатать(v) - оттиски 4 конец Распечатать(v) - оттиски 2конецРаспечатать(v) - оттиски 1
Python
Следующее Python код предоставляет еще один пример затенения переменных:
Икс = 0def внешний(): Икс = 1 def внутренний(): Икс = 2 Распечатать("внутренний:", Икс) внутренний() Распечатать("внешний:", Икс)внешний()Распечатать("Глобальный:", Икс)# отпечаток# внутренний: 2# внешний: 1# глобальный: 0
Поскольку в Python нет объявления переменных, а только присваивание переменных, ключевое слово нелокальный
введенный в Python 3, используется для предотвращения затенения переменных и назначения нелокальным переменным:
Икс = 0def внешний(): Икс = 1 def внутренний(): нелокальный Икс Икс = 2 Распечатать("внутренний:", Икс) внутренний() Распечатать("внешний:", Икс)внешний()Распечатать("Глобальный:", Икс)# отпечаток# внутренний: 2# внешний: 2# глобальный: 0
Ключевое слово Глобальный
используется, чтобы избежать затенения переменных и присвоить глобальным переменным:
Икс = 0def внешний(): Икс = 1 def внутренний(): Глобальный Икс Икс = 2 Распечатать("внутренний:", Икс) внутренний() Распечатать("внешний:", Икс)внешний()Распечатать("Глобальный:", Икс)# отпечаток# внутренний: 2# внешний: 1# глобальный: 2
Ржавчина
fn основной(){позволятьИкс=0;{позволятьИкс=1;println!("Внутренний x: {}",Икс);// выводит 1}println!("Внешний x: {}",Икс);// выводит 0// ТеньпозволятьИкс="Ржавчина";println!("Внешний x: {}",Икс);// выводит 'Rust'}// # Внутренний x: 1// # Внешний x: 0// # Внешний x: Rust
C ++
#включают <iostream>int основной(){ int Икс = 42; int сумма = 0; для (int я = 0; я < 10; я++) { int Икс = я; стандартное::cout << "Икс: " << Икс << ''; // выводит значения i от 0 до 9 сумма += Икс; } стандартное::cout << "сумма:" << сумма << ''; стандартное::cout << "Икс: " << Икс << ''; // выводит 42 вернуть 0;}
Ява
общественный класс Тень { частный int myIntVar = 0; общественный пустота shadowTheVar() { // поскольку оно имеет то же имя, что и поле экземпляра объекта выше, оно затеняется над // поле внутри этого метода int myIntVar = 5; // Если мы просто обратимся к myIntVar, будет найден один из этих методов // (затенение второго с таким же именем) Система.вне.println(myIntVar); // выводит 5 // Если мы хотим сослаться на затененный myIntVar из этого класса, нам нужно // обращайтесь к нему так: Система.вне.println(этот.myIntVar); // выводит 0 } общественный статический пустота основной(Строка[] аргументы){ новый Тень().shadowTheVar(); }}
JavaScript
Введение в ECMAScript 6 `let` и` const` с блочной областью видимости позволяет затенение переменных.
функция myFunc() { позволять my_var = 'тест'; если (правда) { позволять my_var = 'новый тест'; консоль.журнал(my_var); // новый тест } консоль.журнал(my_var); // тест}myFunc();