Skip to content

Constantes en Go

El valor de una constante no puede cambiar en tiempo de ejecución, una vez asignado no se puede modificar, su valor solo puede provenir de:

  • Literales
  • Otros identificadores de constantes
  • Expresiones constantes
  • Conversiones de tipo que resultan en constantes
  • iota

Las constantes solo pueden ser de tipos de datos básicos, no pueden ser

  • Tipos diferentes a los básicos, como estructuras, interfaces, slices, arrays, etc.
  • Valores de retorno de funciones

El valor de una constante no puede ser modificado, de lo contrario no compilará

Inicialización

La declaración de constantes requiere la palabra clave const, una constante debe inicializarse con un valor al declararse, y el tipo de la constante puede omitirse, por ejemplo

go
const name string = "Jack" // literal

const msg = "hello world" // literal

const num = 1 // literal

const numExpression = (1+2+3) / 2 % 100 + num // expresión constante

Si solo se declara sin especificar un valor, no compilará

go
const name string

El compilador reportará un error

missing init expr for name

La declaración de múltiples constantes se puede agrupar con () para mejorar la legibilidad, puede haber múltiples () para lograr un efecto de agrupación.

go
const (
   Count = 1
   Name  = "Jack"
)

const (
   Size = 16
   Len  = 25
)

En el mismo grupo de constantes, las constantes que siguen a una constante ya asignada pueden no tener asignación, su valor por defecto es el valor de la anterior, por ejemplo

go
const (
  A = 1
  B // 1
  C // 1
  D // 1
  E // 1
)

iota

iota es un identificador de constante incorporado, generalmente se usa para representar un número entero sin tipo ordinal en una declaración de constantes, generalmente se usa entre paréntesis.

go
const iota = 0

Veamos algunos casos de uso

go
const (
   Num = iota // 0
   Num1 // 1
   Num2 // 2
   Num3 // 3
   Num4 // 4
)

También se puede escribir así

go
const (
   Num = iota*2 // 0
   Num1 // 2
   Num2 // 4
   Num3 // 6
   Num4 // 8
)

También se puede

go
const (
   Num = iota << 2*3 + 1 // 1
   Num1 // 13
   Num2 // 25
   Num3 = iota // 3
   Num4 // 4
)

A través de los ejemplos anteriores se puede descubrir que iota es incremental, la primera constante usa una expresión con el valor de iota, y según el cambio del número ordinal se asignará automáticamente a las constantes siguientes, hasta que se reinicie con un nuevo const, este número ordinal es en realidad el número de línea relativo del código, es el número de línea relativo a la línea inicial del grupo actual, veamos el siguiente ejemplo

go
const (
  Num  = iota<<2*3 + 1 // 1 primera línea
  Num2 = iota<<2*3 + 1 // 13 segunda línea
  _ // 25 tercera línea
  Num3 //37 cuarta línea
  Num4 = iota // 4 quinta línea
  _ // 5 sexta línea
  Num5 // 6 séptima línea
)

En el ejemplo se usó el identificador anónimo _ para ocupar una posición de línea, se puede ver que el valor de iota es esencialmente la diferencia entre la línea donde está iota y la primera línea del grupo const actual. Los diferentes grupos de const no se afectan entre sí.

Enumeraciones

Go no diseñó un tipo de datos separado para las enumeraciones, a diferencia de otros lenguajes que generalmente tienen un enum para representarlas. Generalmente en Go, se implementan las enumeraciones mediante tipo personalizado + const + iota, un ejemplo simple es el siguiente

go
type Season uint8

const (
  Spring Season = iota
  Summer
  Autumn
  Winter
)

Estas enumeraciones son en realidad números, Go tampoco soporta convertirlas directamente a cadenas, pero podemos agregar métodos al tipo personalizado para devolver su representación en cadena, implementando la interfaz Stringer.

go
func (s Season) String() string {
  switch s {
  case Spring:
    return "spring"
  case Summer:
    return "summer"
  case Autumn:
    return "autumn"
  case Winter:
    return "winter"
  }
  return ""
}

Así se implementa una enumeración simple. También puedes usar la herramienta oficial Stringer para generar automáticamente las enumeraciones.

Sin embargo, tiene las siguientes desventajas:

  • No es seguro en cuanto a tipos, porque Season es un tipo personalizado, se pueden convertir otros números a este tipo mediante conversión forzada

    go
    Season(6)
  • Tedioso, la representación en cadena debe implementarse uno mismo

  • Capacidad de expresión limitada, porque const solo soporta tipos de datos básicos, por lo que estos valores de enumeración solo pueden representarse con cadenas y números

Por qué no soportar enumeraciones a nivel del lenguaje es algo que el autor no puede entender, creo que definitivamente sería más ventajoso que desventajoso.

Golang editado por www.golangdev.cn