Variables en el lenguaje Go
Las variables provienen de las matemáticas; en los lenguajes de computación son conceptos abstractos que pueden almacenar resultados de cálculos o representar valores.
Las variables se pueden acceder mediante el nombre de la variable.
Los nombres de variables en Go se componen de letras, dígitos y guiones bajos, y el primer carácter no puede ser un dígito.
La forma general de declarar variables es usando la palabra clave var:
var identifier type
Se pueden declarar múltiples variables a la vez:
var identifier1, identifier2 type
Ejemplo
import "fmt"
func main() {
var a string = "Ejemplo"
fmt.Println(a)
var b, c int = 1, 2
fmt.Println(b, c)
}
El resultado del ejemplo anterior es:
Ejemplo 1 2
Declaración de variables
Primera forma: especificar el tipo de variable. Si no se inicializa, la variable toma por defecto el valor cero.。
var v_name v_type v_name = value
El valor cero es el valor que el sistema asigna por defecto cuando la variable no se ha inicializado.
Ejemplo
import "fmt"
func main() {
// declarar una variable e inicializarla
var a = "EJEMPLO"
fmt.Println(a)
// sin inicializar, es el valor cero
var b int
fmt.Println(b)
// el valor cero de bool es false
var c bool
fmt.Println(c)
}
El resultado de ejecutar el ejemplo anterior es:
EJEMPLO 0 false
Los tipos numéricos (incluidos complex64/128) son0
-
El tipo booleano esfalse
-
La cadena es""(cadena vacía)
Los siguientes tipos sonnil:
var a *int var a []int var a map[string] int var a chan int var a func(string) int var a error // error 是接口
Ejemplo
import "fmt"
func main() {
var i int
var f float64
var b bool
var s string
fmt.Printf("%v %v %v %q\n", i, f, b, s)
}
El resultado de salida es:
0 0 false ""
Segunda forma: el tipo de variable se determina automáticamente según el valor.
var v_name = value
Ejemplo
import "fmt"
func main() {
var d = true
fmt.Println(d)
}
El resultado de salida es:
true
Tercera forma: si una variable ya ha sido declarada con var, usar nuevamente:=para declarar la variable produce un error de compilación. Formato:
v_name := value
Por ejemplo:
var intVal int intVal :=1 // 这时候会产生编译错误,因为 intVal 已经声明,不需要重新声明
Simplemente use la siguiente declaración:
intVal := 1 // 此时不会产生编译错误,因为有声明新的变量,因为 := 是一个声明语句
intVal := 1Equivale a:
var intVal int intVal =1
Se puede simplificar var f string = "Ejemplo" a f := "Ejemplo":
Ejemplo
import "fmt"
func main() {
f := "Ejemplo" // var f string = "Ejemplo"
fmt.Println(f)
}
El resultado de salida es:
Ejemplo
Declaración de múltiples variables
//类型相同多个变量, 非全局变量
var vname1, vname2, vname3 type
vname1, vname2, vname3 = v1, v2, v3
var vname1, vname2, vname3 = v1, v2, v3 // 和 python 很像,不需要显示声明类型,自动推断
vname1, vname2, vname3 := v1, v2, v3 // 出现在 := 左侧的变量不应该是已经被声明过的,否则会导致编译错误
// 这种因式分解关键字的写法一般用于声明全局变量
var (
vname1 v_type1
vname2 v_type2
)
Ejemplo
import "fmt"
var x, y int
var ( // Esta forma de factorización con palabras clave generalmente se usa para declarar variables globales
a int
b bool
)
var c, d int = 1, 2
var e, f = 123, "hello"
// Esta forma sin declaración solo puede aparecer dentro del cuerpo de una función
//g, h := 123, "hello"
func main(){
g, h := 123, "hello"
fmt.Println(x, y, a, b, c, d, e, f, g, h)
}
El resultado de ejecutar el ejemplo anterior es:
0 0 0 false 1 2 123 hello 123 hello
Tipos de valor y tipos de referencia
Todos los tipos básicos como int, float, bool y string pertenecen a los tipos de valor. Las variables de estos tipos apuntan directamente al valor almacenado en la memoria:
Cuando se usa el signo igual=para asignar el valor de una variable a otra variable, por ejemplo:j = i, en realidad se copia el valor de i en la memoria:
Puede obtener la dirección de memoria de la variable i mediante &i, por ejemplo: 0xf840000040 (la dirección puede ser diferente cada vez).
Las variables de tipo de valor generalmente se almacenan en la pila, especialmente cuando son variables locales. Cuando el valor de una variable de tipo de valor necesita usarse fuera del ámbito de la función, Go la asigna a la memoria del montón.
Las direcciones de memoria varían según la máquina; incluso el mismo programa ejecutado en diferentes máquinas puede tener diferentes direcciones de memoria, porque cada máquina puede tener una disposición de memoria distinta y la asignación de ubicaciones también puede ser diferente.
Los datos más complejos generalmente requieren el uso de múltiples palabras; estos datos suelen guardarse mediante tipos de referencia.
Una variable de tipo de referencia r1 almacena la dirección de memoria (un número) donde se encuentra el valor de r1, o la posición de la primera palabra en esa dirección de memoria.
Esta dirección de memoria se denomina puntero; de hecho, este puntero también se almacena en algún otro valor.
Las múltiples palabras a las que apunta el puntero de un mismo tipo de referencia pueden estar en direcciones de memoria contiguas (la disposición de memoria es continua), lo que también es la forma de almacenamiento con mayor eficiencia computacional; también se pueden almacenar estas palabras dispersas en la memoria, donde cada palabra indica la dirección de memoria de la siguiente palabra.
Cuando se usa la sentencia de asignación r2 = r1, solo se copia la referencia (la dirección).
Si el valor de r1 cambia, todas las referencias a ese valor apuntarán al contenido modificado; en este ejemplo, r2 también se verá afectada.
Forma abreviada, usando el operador de asignación :=
Sabemos que al inicializar una variable se puede omitir el tipo y dejar que el sistema lo infiera automáticamente; escribir la palabra clave var en la declaración resulta algo redundante, por lo que podemos abreviarlo como a := 50 o b := false.
Los tipos de a y b (int y bool) serán inferidos automáticamente por el compilador.
Esta es la forma preferida de usar variables, pero solo se puede usar dentro del cuerpo de una función; no se puede usar para declarar ni asignar variables globales. Usar el operador := permite crear eficientemente una nueva variable; se denomina declaración de inicialización.
Notas
En el mismo bloque de código, no podemos usar una declaración de inicialización nuevamente para una variable con el mismo nombre; por ejemplo, a := 20 no está permitido, y el compilador mostrará el error "no new variables on left side of :=". Sin embargo, a = 20 sí es válido, porque esto asigna un nuevo valor a la misma variable.
Si usas la variable a antes de definirla, obtendrás un error de compilación: undefined: a.
Si declaras una variable local pero no la usas en el mismo bloque de código, también obtendrás un error de compilación, como la variable a en el siguiente ejemplo:
Ejemplo
import "fmt"
func main() {
var a string = "abc"
fmt.Println("hello, world")
}
Intentar compilar este código dará el errora declared but not used。
Además, no basta con asignar un valor a a; ese valor debe ser utilizado, por lo que usar
fmt.Println("hello, world", a)eliminará el error.
Sin embargo, las variables globales pueden declararse sin usarse. Varias variables del mismo tipo pueden declararse en la misma línea, por ejemplo:
var a, b, c int
Múltiples variables pueden asignarse en la misma línea, por ejemplo:
var a, b int var c string a, b, c = 5, 7, "abc"
La línea anterior supone que las variables a, b y c ya han sido declaradas; de lo contrario, debería usarse así:
a, b, c := 5, 7, "abc"
Los valores de la derecha se asignan a las variables de la izquierda en el mismo orden, por lo que el valor de a es 5, el valor de b es 7 y el valor de c es "abc".
Esto se denomina asignación paralela o simultánea.
Si deseas intercambiar los valores de dos variables, simplemente puedes usara, b = b, a, los tipos de ambas variables deben ser los mismos.
El identificador en blanco _ también se utiliza para descartar valores; por ejemplo, el valor 5 en _, b = 5, 7 es descartado.
_ es en realidad una variable de solo escritura; no puedes obtener su valor. Esto se debe a que en Go debes usar todas las variables declaradas, pero a veces no necesitas usar todos los valores de retorno de una función.
La asignación paralela también se usa cuando una función devuelve múltiples valores de retorno; por ejemplo, aquí val y el error err se obtienen simultáneamente llamando a la función Func1: val, err = Func1(var1).
Otras extensiones