Jump to content

Переменное затенение

В программировании компьютерном затенение переменных происходит, когда переменная, объявленная в определенной области (блоке принятия решений, методе или внутреннем классе ), имеет то же имя, что и переменная, объявленная во внешней области. На уровне идентификаторов (имен, а не переменных) это называется маскированием имени . Говорят, что эта внешняя переменная затенена внутренней переменной, тогда как внутренний идентификатор маскирует внешний идентификатор. Это может привести к путанице, поскольку может быть неясно, к какой переменной относятся последующие использования имени затененной переменной, что зависит от правил разрешения имен языка.

Одним из первых языков, в котором было реализовано затенение переменных, был 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();

См. также [ править ]

Ссылки [ править ]

  1. ^ «От Java к Котлину и обратно» . Архивировано из оригинала 28 ноября 2020 г. Проверено 4 октября 2021 г.
  2. ^ «Пожалуйста, введите явное затенение · Проблема № 2697 · jashkenas/Coffeescript» . Гитхаб . Архивировано из оригинала 04 октября 2021 г. Проверено 4 октября 2021 г.
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: bd9c68d98ffbf73f89ef195c40c2fe98__1714567920
URL1:https://arc.ask3.ru/arc/aa/bd/98/bd9c68d98ffbf73f89ef195c40c2fe98.html
Заголовок, (Title) документа по адресу, URL1:
Variable shadowing - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)