Variabilní stínování - Variable shadowing

V programování počítače , variabilní zastínění dochází při proměnné deklarované v určitém rozsahu (rozhodovacím bloku, metoda nebo vnitřní třídy ) má stejný název jako proměnné deklarované ve vnějším rozsahu. Na úrovni identifikátorů (názvy, nikoli proměnné) se tomu říká maskování jmen . O této vnější proměnné se říká, že je zastíněna vnitřní proměnnou, zatímco vnitřní identifikátor údajně maskuje vnější identifikátor. To může vést ke zmatku, protože může být nejasné, na kterou proměnnou se následující použití názvu stínované proměnné vztahuje, což závisí na pravidlech rozlišení názvu jazyka.

Jedním z prvních jazyků, které zavedly variabilní stínování, byl ALGOL , který jako první zavedl bloky pro vytváření oborů. Bylo to také povoleno mnoha odvozenými programovacími jazyky včetně C , C ++ a Java .

Jazyk C# tuto tradici porušuje, umožňuje variabilní stínování mezi vnitřní a vnější třídou a mezi metodou a její obsahující třídou, ale nikoli mezi if-block a její obsahující metodou nebo mezi příkazy case v přepínacím bloku.

Některé jazyky umožňují variabilní stínování ve více případech než jiné. Například Kotlin umožňuje vnitřní proměnné ve funkci stínovat předaný argument a proměnné ve vnitřním bloku stínovat jiné ve vnějším bloku, zatímco Java je neumožňuje. Oba jazyky umožňují předaný argument funkci/metodě stínovat pole třídy.

Některé jazyky zcela znemožňují variabilní stínování, například CoffeeScript .

Příklad

Lua

Následující kód Lua poskytuje příklad proměnného stínování ve více blocích.

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

Krajta

Následující kód Pythonu poskytuje další příklad stínování proměnných:

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

Protože v Pythonu neexistuje žádná deklarace proměnných, ale pouze přiřazení proměnných, používá se klíčové slovo nonlocalzavedené v Pythonu 3, aby se zabránilo stínování proměnných a přiřazování nelokálním proměnným:

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

Klíčové slovo globalslouží k zamezení stínování proměnných a přiřazení ke globálním proměnným:

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

Rez

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;
}

Jáva

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

Zavedení výrazů „let` a„ const` v bloku ECMAScript 6 s blokováním umožňuje variabilní stínování.

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();

Viz také

Reference

  1. ^ "Archivovaná kopie" . Archivováno od originálu dne 2020-11-28 . Citováno 2021-10-04 .CS1 maint: archivovaná kopie jako název ( odkaz )
  2. ^ "Archivovaná kopie" . Archivováno od originálu dne 2021-10-04 . Citováno 2021-10-04 .CS1 maint: archivovaná kopie jako název ( odkaz )