En la programación de computadoras , el sombreado de variables ocurre cuando una variable declarada dentro de un cierto alcance (bloque de decisión, método o clase interna ) tiene el mismo nombre que una variable declarada en un alcance externo. A nivel de identificadores (nombres, en lugar de variables), esto se conoce como enmascaramiento de nombres . Se dice que esta variable externa está sombreada por la variable interna, mientras que se dice que el identificador interno enmascara el identificador externo. Esto puede generar confusión, ya que puede no estar claro a qué variable se refieren los usos posteriores del nombre de la variable sombreada, lo que depende de las reglas de resolución de nombres del idioma.
Uno de los primeros lenguajes en introducir el sombreado de variables fue ALGOL , que introdujo por primera vez bloques para establecer ámbitos. También fue permitido por muchos de los lenguajes de programación derivados, incluidos C , C ++ y Java .
El lenguaje C # rompe esta tradición, permitiendo el sombreado de variables entre una clase interna y una externa, y entre un método y su clase contenedora, pero no entre un bloque if y su método contenedor, o entre sentencias case en un bloque switch .
Algunos lenguajes permiten el sombreado variable en más casos que otros. Por ejemplo, Kotlin permite que una variable interna en una función sombree un argumento pasado y una variable en un bloque interno para sombrear otra en un bloque externo, mientras que Java no los permite. Ambos lenguajes permiten que un argumento pasado a una función / método haga sombra a un campo de clase. [1]
Algunos lenguajes no permiten el sombreado de variables por completo, como CoffeeScript . [2]
Ejemplo
Lua
El siguiente código de Lua proporciona un ejemplo de sombreado de variables, en varios bloques.
v = 1 - una variable globalhacer local v = v + 1 - un nuevo local que sombrea global v print ( v ) - imprime 2 do local v = v * 2 - otro local que sombrea el local externo v print ( v ) - imprime 4 end imprimir ( v ) - imprime 2 al finalimprimir ( v ) - imprime 1
Pitón
El siguiente código de Python proporciona otro ejemplo de sombreado de variables:
x = 0def exterior (): x = 1 def inner (): x = 2 print ( "interno:" , x ) inner () print ( "externo:" , x )exterior () imprimir ( "global:" , x )# impresiones # interior: 2 # exterior: 1 # global: 0
Como no hay declaración de variable, sino solo asignación de variable en Python, la palabra clave nonlocal
introducida en Python 3 se usa para evitar el sombreado de variables y asignar a variables no locales:
x = 0def exterior (): x = 1 def inner (): no local x x = 2 print ( "inner:" , x ) inner () print ( "externo:" , x )exterior () imprimir ( "global:" , x )# impresiones # interior: 2 # exterior: 2 # global: 0
La palabra clave global
se utiliza para evitar el sombreado de variables y asignarlas a variables globales:
x = 0def exterior (): x = 1 def inner (): global x x = 2 print ( "interno:" , x ) inner () print ( "externo:" , x )exterior () imprimir ( "global:" , x )# impresiones # interior: 2 # exterior: 1 # global: 2
Oxido
fn main () { sea x = 0 ; { sea x = 1 ; println! ( "Interior x: {}" , x ); // imprime 1 } println! ( "Exterior x: {}" , x ); // imprime 0 // Shadow let x = "Rust" ; println! ( "Exterior x: {}" , x ); // imprime 'Rust' } // # Interior x: 1 // # Exterior x: 0 // # Exterior x: Óxido
C ++
#include int main () { int x = 42 ; int suma = 0 ; para ( int i = 0 ; i < 10 ; i ++ ) { int x = i ; std :: cout << "x:" << x << '\ n' ; // imprime valores de i de 0 a 9 suma + = x ; } std :: cout << "suma:" << suma << '\ n' ; std :: cout << "x:" << x << '\ n' ; // imprime 42 return 0 ; }
Java
Shadow de clase pública { private int myIntVar = 0 ; public void shadowTheVar () { // Dado que tiene el mismo nombre que el campo de instancia del objeto anterior, sombrea el // campo dentro de este método. int myIntVar = 5 ; // Si simplemente nos referimos a 'myIntVar' se encuentra el de este método // (sombreando un segundo con el mismo nombre) System . fuera . println ( myIntVar ); // imprime 5 // Si queremos referirnos al myIntVar sombreado de esta clase, necesitamos // referirnos a él así: System . fuera . println ( este . myIntVar ); // imprime 0 } public static void main ( String [] args ) { new Shadow ( "rojo" ). shadowTheVar (); } }
JavaScript
La introducción de ECMAScript 6 de `let` y` const` con alcance de bloque permite el sombreado variable.
function myFunc () { let my_var = 'prueba' ; if ( verdadero ) { let my_var = 'nueva prueba' ; consola . log ( my_var ); // nueva prueba } consola . log ( my_var ); // prueba } myFunc ();