En programación informática , el sombreado de variables se produce cuando una variable declarada dentro de un ámbito determinado (bloque de decisión, método o clase interna ) tiene el mismo nombre que una variable declarada en un ámbito 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 al 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 lenguaje.
Uno de los primeros lenguajes en introducir el sombreado de variables fue ALGOL , que fue el primero en introducir bloques para establecer ámbitos. También lo permitieron muchos de los lenguajes de programación derivados, entre ellos 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 declaraciones de caso en un bloque switch .
Algunos lenguajes permiten el sombreado de variables en más casos que otros. Por ejemplo, Kotlin permite que una variable interna en una función sombree un argumento pasado y que una variable en un bloque interno sombree a otra en un bloque externo, mientras que Java no permite esto. Ambos lenguajes permiten que un argumento pasado a una función/método sombree un campo de clase. [1]
Algunos lenguajes no permiten el sombreado de variables por completo, como CoffeeScript [2] y V (Vlang) . [3]
El siguiente código Lua proporciona un ejemplo de sombreado de variables en múltiples bloques.
v = 1 -- una variable globalhacer local v = v + 1 -- un nuevo local que sombrea global v print ( v ) -- imprime 2 hacer v local = v * 2 -- otro local que sombrea el local externo v print ( v ) -- imprime 4 fin imprimir ( v ) -- imprime 2 finalesimprimir ( v ) -- imprime 1
El siguiente código Python proporciona otro ejemplo de sombreado de variables:
x = 0def exterior (): x = 1 def interior (): x = 2 print ( "interior:" , x ) interior () imprimir ( "exterior:" , x )exterior () imprimir ( "global:" , x )# impresiones # interior: 2 # exterior: 1 # global: 0
Como en Python no hay declaración de variables sino solo asignación de variables, nonlocal
se utiliza la palabra clave introducida en Python 3 para evitar el sombreado de variables y asignar a variables no locales:
x = 0def exterior (): x = 1 def interior (): no local x x = 2 print ( "interior:" , x ) interior () imprimir ( "exterior:" , 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 interior (): global x x = 2 print ( "interior:" , x ) interior () imprimir ( "exterior:" , x )exterior () imprimir ( "global:" , x )# impresiones # interior: 2 # exterior: 1 # global: 2
fn main () { let x = 0 ; { // Sombra let x = 1 ; println! ( "Interior x: {}" , x ); // imprime 1 } println! ( "Exterior x: {}" , x ); // imprime 0 let x = "Óxido" ; println! ( "Exterior x: {}" , x ); // imprime 'Óxido' } //# Interior x: 1 //# Exterior x: 0 //# Exterior x: Óxido
#include <flujo de datos> int principal () { int x = 42 ; int suma = 0 ; for ( 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' ; // imprime 45 std :: cout << "x: " << x << '\n' ; // imprime 42 devuelve 0 ; }
clase pública Sombra { int privado 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 hacemos referencia a 'myIntVar' se encuentra el de este método // (haciendo sombra a un segundo con el mismo nombre) System . out . println ( myIntVar ); // imprime 5 // Si queremos hacer referencia a la myIntVar sombreada desde esta clase, necesitamos hacer referencia a ella de esta manera: System . out . println ( this . myIntVar ); // imprime 0 } public static void main ( String [] args ){ new Shadow (). shadowTheVar (); } }
La introducción de ECMAScript 6let
con const
alcance de bloque permite el sombreado de variables.
función myFunc () { let my_var = ' prueba' ; if ( true ) { let my_var = ' nueva prueba' ; console.log ( my_var ) ; // nueva prueba } console.log ( my_var ); // prueba } myFunc () ;