Переменное затенение - 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();

Смотрите также

использованная литература