Skip to content

Variables en Go

Una variable es una ubicación de almacenamiento para guardar un valor, permite que su valor cambie dinámicamente durante la ejecución. Al declarar una variable, se le asigna un bloque de memoria para almacenar el valor del tipo correspondiente. Para más detalles, ve a manual de referencia - Variables.

Declaración

En Go, la declaración de tipos es postfix, la declaración de variables usa la palabra clave var, el formato es var nombreVariable nombreTipo. Las reglas de nomenclatura de variables deben cumplir con las reglas de nomenclatura de identificadores.

go
var intNum int
var str string
var char byte

Cuando se quieren declarar múltiples variables del mismo tipo, solo se necesita escribir el tipo una vez:

go
var numA, numB, numC int

Cuando se quieren declarar múltiples variables de diferentes tipos, se puede usar () para envolverlas, puede haber múltiples ().

go
var (
  name    string
  age     int
  address string
)

var (
  school string
  class int
)

Si una variable solo se declara sin asignar un valor, el valor almacenado en la variable es el valor cero del tipo correspondiente.

Asignación

La asignación usa el operador =, por ejemplo:

go
var name string
name = "jack"

También se puede asignar un valor directamente al declarar:

go
var name string = "jack"

O también se puede hacer así:

go
var name string
var age int
name, age = "jack", 1

La segunda forma requiere especificar el tipo cada vez, se puede usar el azúcar sintáctico proporcionado oficialmente: inicialización corta de variables, que permite omitir la palabra clave var y el tipo postfix, el compilador infiere el tipo específico.

go
name := "jack" // variable de tipo cadena

Aunque no se necesita especificar el tipo, en asignaciones posteriores el tipo debe ser consistente, el siguiente código no puede compilar:

a := 1
a = "1"

También hay que tener en cuenta que la inicialización corta de variables no puede usar nil, porque nil no pertenece a ningún tipo, el compilador no puede inferir su tipo.

go
name := nil // no puede compilar

La declaración corta de variables puede inicializar múltiples variables a la vez:

go
name, age := "jack", 1

La declaración corta de variables no se puede usar para una variable que ya existe, por ejemplo:

go
// Ejemplo incorrecto
var a int
a := 1

// Ejemplo incorrecto
a := 1
a := 2

Pero hay una excepción, cuando al asignar a variables antiguas también se declara una nueva variable, por ejemplo:

go
a := 1
a, b := 2, 2

Este código puede compilar, la variable a es reasignada, mientras que b es la nueva declarada.

En Go hay una regla, todas las variables en funciones deben ser usadas, por ejemplo el siguiente código solo declara la variable pero no la usa:

go
func main() {
  a := 1
}

Entonces al compilar habrá un error, indicando que la variable se declaró pero no se usó:

a declared and not used

Esta regla solo aplica a variables dentro de funciones, para variables a nivel de paquete fuera de las funciones no hay esta limitación, el siguiente código puede compilar:

go
var a = 1

func main() {

}

Anónimo

Se puede usar un guión bajo para indicar que no se necesita una variable:

go
Open(name string) (*File, error)

Por ejemplo, la función os.Open tiene dos valores de retorno, solo queremos el primero, no el segundo, se puede escribir así:

go
file, _ := os.Open("readme.txt")

Las variables no usadas no pueden compilar, cuando no se necesita una variable, se puede usar el guión bajo _ en su lugar.

Intercambio

En Go, si se quiere intercambiar los valores de dos variables, no se necesitan usar punteros, se puede usar el operador de asignación para intercambiar directamente. La sintaxis es muy intuitiva, por ejemplo:

go
num1, num2 := 25, 36
num1, num2 = num2, num1

Lo mismo aplica para tres variables:

go
num1, num2, num3 := 25, 36, 49
num1, num2, num3  = num3, num2, num1

Piensa en el siguiente código, es un fragmento para calcular la secuencia de Fibonacci, después del cálculo, ¿cuáles son los valores de las tres variables?

go
a, b, c := 0, 1, 1
a, b, c = b, c, a+b

La respuesta es:

1 1 1

Podrías preguntarte por qué no es:

1 1 2

Siendo que a ya tiene el valor de b, ¿por qué el resultado de a+b sigue siendo 1? En Go, al realizar operaciones de asignación de múltiples variables, el orden es calcular primero los valores y luego asignar, no de izquierda a derecha.

go
a, b, c = b, c, a+b

Podrías pensar que se expande a:

go
a = b
b = c
c = a + b

Pero en realidad calcula los valores de a, b, c primero y luego los asigna, equivale a:

go
a, b, c = 1, 1, 0+1

Cuando involucra llamadas a funciones, este efecto es aún más evidente. Tenemos una función sum que puede calcular el valor de retorno de dos números:

go
func sum(a, b int) int {
  return a + b
}

Sumar dos números mediante una función:

go
a, b, c := 0, 1, 1
a, b, c = b, c, sum(a, b)

El resultado no cambia, al calcular el valor de retorno de la función sum, sus parámetros de entrada siguen siendo 0 y 1:

1 1 1

Por lo tanto, el código debería escribirse así por separado:

go
a, b = b, c
c = a + b

Comparación

Hay un requisito previo importante para la comparación entre variables, sus tipos deben ser iguales. Go no tiene conversión implícita de tipos, un código como el siguiente no puede compilar:

go
func main() {
  var a uint64
  var b int64
  fmt.Println(a == b)
}

El compilador indicará que los tipos de ambos son diferentes:

invalid operation: a == b (mismatched types uint64 and int64)

Por lo tanto, se debe usar conversión explícita de tipos:

go
func main() {
  var a uint64
  var b int64
  fmt.Println(int64(a) == b)
}

Antes de los genéricos, las funciones incorporadas min y max que Go proporcionaba solo soportaban números de punto flotante. En la versión 1.21, Go finalmente reescribió estas dos funciones incorporadas con genéricos, ahora se puede usar la función min para comparar el valor mínimo:

go
minVal := min(1, 2, -1, 1.2)

Usar la función max para comparar el valor máximo:

go
maxVal := max(100, 22, -1, 1.12)

Sus parámetros soportan todos los tipos comparables, los tipos comparables en Go son:

  • Booleanos
  • Números
  • Cadenas
  • Punteros
  • Canales (solo soportan verificar si son iguales)
  • Arrays cuyos elementos son tipos comparables (los slices no son comparables) (solo soportan verificar si son iguales) (solo soportan comparación entre arrays de la misma longitud, porque la longitud del array también es parte del tipo, y tipos diferentes no son comparables)
  • Estructuras cuyos tipos de campos son todos comparables (solo soportan verificar si son iguales)

Además, también se puede importar la biblioteca estándar cmp para comparar, pero solo soporta parámetros de tipos ordenados. En Go, los tipos ordenados incorporados son solo números y cadenas.

go
import "cmp"

func main() {
  cmp.Compare(1, 2)
  cmp.Less(1, 2)
}

Bloques de código

Dentro de una función, se puede establecer un bloque de código mediante llaves, los ámbitos de las variables entre bloques de código son independientes entre sí. Por ejemplo, el siguiente código:

go
func main() {
  a := 1

  {
    a := 2
    fmt.Println(a)
  }

  {
    a := 3
    fmt.Println(a)
  }
  fmt.Println(a)
}

Su salida es:

2
3
1

Las variables entre bloques son independientes, no se interfieren entre sí, no se pueden acceder, pero pueden verse afectadas por el bloque padre:

go
func main() {
  a := 1

  {
    a := 2
    fmt.Println(a)
  }

  {
    fmt.Println(a)
  }
  fmt.Println(a)
}

Su salida es:

2
1
1

Golang editado por www.golangdev.cn