Variabel skygge - Variable shadowing

I edb-programmering , variabel shadowing opstår, når en variabel erklæret inden for en bestemt omfang (beslutning blok, metode, eller indre klasse ) har samme navn som en variabel erklæret i en ydre omfang. På niveau med identifikatorer (navne, snarere end variabler) er dette kendt som navnemaskering . Denne ydre variabel siges at være skygget af den indre variabel, mens den indre identifikator siges at maskere den ydre identifikator. Dette kan føre til forvirring, da det kan være uklart, hvilke variable senere brug af skygget variabelnavn refererer til, hvilket afhænger af de navn opløsning regler sproget.

Et af de første sprog, der introducerede variabel skygge, var ALGOL , som først introducerede blokke til etablering af omfang. Det var også tilladt af mange af de afledte programmeringssprog, herunder C , C ++ og Java .

Den C # sprog bryder denne tradition, tillader variabel shadowing mellem en indre og en ydre klasse og mellem en fremgangsmåde og dens indhold klasse, men ikke mellem en if-blok og dens indhold metode, eller mellem case udsagn i en switch blok.

Nogle sprog tillader variabel skygge i flere tilfælde end andre. For eksempel tillader Kotlin en indre variabel i en funktion at skygge et bestået argument og en variabel i den indre blok for at skygge en anden i den ydre blok, mens Java ikke tillader disse. Begge sprog tillader et videregivet argument til en funktion/metode at skygge et klassefelt.

Nogle sprog tillader ikke, at variabel skygge er fuldstændig, f.eks. CoffeeScript .

Eksempel

Lua

Den følgende Lua -kode giver et eksempel på variabel skygge i flere blokke.

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

Den følgende Python -kode giver et andet eksempel på variabel skygge:

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

Da der ikke er nogen variabeldeklaration, men kun variabel tildeling i Python, bruges søgeordet, der blev nonlocalintroduceret i Python 3, for at undgå variabel skygge og tildele til ikke-lokale variabler:

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

Nøgleordet globalbruges til at undgå variabel skygge og tildele globale variabler:

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

Rust

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

Java

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 introduktion af 'lad' og 'const' med blokomfang tillader variabel skygge.

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

Se også

Referencer

  1. ^ "Arkiveret kopi" . Arkiveret fra originalen 2020-11-28 . Hentet 2021-10-04 .CS1 maint: arkiveret kopi som titel ( link )
  2. ^ "Arkiveret kopi" . Arkiveret fra originalen 2021-10-04 . Hentet 2021-10-04 .CS1 maint: arkiveret kopi som titel ( link )