¿Dónde podemos usar el alcance variable y el sombreado en Go?
scope lexical-scope (1)
Algunos mensajes relacionados que he encontrado:
- ir de alcance variable y sombreado
- Golang: alcance variable dentro de sentencias if
- Limite el alcance de las variables que almacenan el error
También hay muchos casos de uso para el alcance variable y el sombreado.
Cualquier código de muestras o respuestas será apreciado.
Alcance variable y sombreado
Go tiene un alcance léxico usando bloques:
1-El alcance de un identificador predefinido es el bloque del universo.
2-El alcance de un identificador que denota una constante, tipo, variable o función (pero no método) declarado en el nivel superior (fuera de cualquier función) es el bloque del paquete.
3-El alcance del nombre del paquete de un paquete importado es el bloque de archivo del archivo que contiene la declaración de importación.
4-El alcance de un identificador que denota un receptor de método, un parámetro de función o una variable de resultado es el cuerpo de la función.
5-El alcance de un identificador de constante o variable declarado dentro de una función comienza al final de ConstSpec o VarSpec (ShortVarDecl para declaraciones de variables cortas) y termina al final del bloque que lo contiene más interno.
6-El alcance de un identificador de tipo declarado dentro de una función comienza en el identificador en TypeSpec y termina al final del bloque que lo contiene más interno.
Un identificador declarado en un bloque puede ser redeclarado en un bloque interno.
Mientras que el identificador de la declaración interna está en el alcance, denota la entidad declarada por la declaración interna.La cláusula del paquete no es una declaración; el nombre del paquete no aparece en ningún ámbito. Su objetivo es identificar los archivos que pertenecen al mismo paquete y especificar el nombre del paquete predeterminado para las declaraciones de importación.
Ventajas:
- Dado que no se puede acceder a los datos desde el ámbito externo, se preserva la integridad de los datos
Diferentes formas de sombreado variable en Go:
1- Forma de Golang para limitar el alcance de la variable (usando la asignación de mano corta dentro de las declaraciones):
package main
import "fmt"
func main() {
i := 10 //scope: main
j := 4
for i := ''a''; i < ''b''; i++ {
// i shadowed inside this block
fmt.Println(i, j) //97 4
}
fmt.Println(i, j) //10 4
if i := "test"; len(i) == j {
// i shadowed inside this block
fmt.Println(i, j) // i= test , j= 4
} else {
// i shadowed inside this block
fmt.Println(i, j) //test 40
}
fmt.Println(i, j) //10 4
}
2- Cuando "necesitamos más alfabetos", esta es una buena manera de limitar el alcance de las variables .
También esto funciona bien cuando necesita más variables locales o alcance:
usando {
y }
par:
Pros: no hay necesidad de declaraciones adicionales como si, por, ...
package main
import "fmt"
func main() {
i := 1
j := 2
//new scope :
{
i := "hi" //new local var
j++
fmt.Println(i, j) //hi 3
}
fmt.Println(i, j) //1 3
}
3- Otra forma de limitar el alcance variable es usar llamadas a funciones :
Pros: el límite de alcance, los parámetros de tipo de valor de entrada se pueden usar como variables locales,
Contras: tiempo de llamada / retorno y uso de la pila: si no está optimizado por el compilador
package main
import "fmt"
func fun(i int, j *int) {
i++ //+nice: use as local var without side effect
*j++ //+nice: intentionally use as global var
fmt.Println(i, *j) //11 21
}
func main() {
i := 10 //scope: main
j := 20
fun(i, &j)
fmt.Println(i, j) //10 21
}
4- Otra forma es sombreando las variables globales :
package main
import "fmt"
var i int = 1 //global
func main() {
j := 2
fmt.Println(i, j) //1 2
i := 10 //Shadowing global var
fmt.Println(i, j) //10 2
fun(i, j) //10 2
}
func fun(i, j int) {
//i := 100 //error: no new variables on left side of :=
//var i int = 100 //error: i redeclared in this block
fmt.Println(i, j) //10 2
}
Ver: sombreado variable y alcance .
Y: Declaraciones y alcance :