Skip to content

Constantes do Go

O valor de uma constante não pode ser alterado em tempo de execução, uma vez atribuído não pode mais ser modificado, seu valor só pode vir de

  • Literais
  • Outros identificadores de constantes
  • Expressões constantes
  • Conversões de tipo que resultam em constantes
  • iota

Constantes só podem ser de tipos de dados básicos, não podem ser

  • Outros tipos além dos tipos básicos, como estruturas, interfaces, slices, arrays, etc.
  • Retorno de função

O valor de uma constante não pode ser modificado, caso contrário não compilará

Inicialização

A declaração de uma constante requer a palavra-chave const, uma constante deve ser inicializada com um valor no momento da declaração, e o tipo da constante pode ser omitido, por exemplo

go
const name string = "Jack" // literal

const msg = "hello world" // literal

const num = 1 // literal

const numExpression = (1+2+3) / 2 % 100 + num // expressão constante

Se apenas declarar sem especificar um valor, não compilará

go
const name string

O compilador reportará erro

missing init expr for name

Declaração em lote de constantes pode usar () para agrupar e melhorar a legibilidade, pode haver múltiplos () para criar grupos.

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

const (
   Size = 16
   Len  = 25
)

No mesmo grupo de constantes, constantes após uma constante já atribuída podem não ter valor atribuído, seu valor padrão é o valor da anterior, por exemplo

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

iota

iota é um identificador de constante incorporado, geralmente usado para representar um número inteiro sem tipo ordinal em uma declaração de constante, geralmente usado dentro de parênteses.

go
const iota = 0

Veja alguns casos de uso

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

Também pode escrever assim

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

Ainda pode

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

Através dos exemplos acima, pode-se perceber que iota é incrementado, a primeira constante usa a expressão com valor iota, de acordo com a variação do valor ordinal será automaticamente atribuído às constantes subsequentes, até que um novo const reinicie, este número ordinal é na verdade o número da linha relativa do código, é o número da linha relativa à linha inicial do grupo atual, veja o exemplo abaixo

go
const (
  Num  = iota<<2*3 + 1 // 1 primeira linha
  Num2 = iota<<2*3 + 1 // 13 segunda linha
  _ // 25 terceira linha
  Num3 //37 quarta linha
  Num4 = iota // 4 quinta linha
  _ // 5 sexta linha
  Num5 // 6 sétima linha
)

O exemplo usa o identificador anônimo _ para ocupar uma posição de linha, pode-se ver que o valor de iota é essencialmente a diferença entre a linha onde iota está e a primeira linha do grupo const atual. Diferentes grupos de const não afetam uns aos outros.

Enumeração

Go não projetou um tipo de dados separado para enumeração, diferente de outras linguagens que geralmente têm um enum para representar. Geralmente em Go, enumerações são implementadas através de tipo personalizado + const + iota, abaixo está um exemplo simples

go
type Season uint8

const (
  Spring Season = iota
  Summer
  Autumn
  Winter
)

Estas enumerações são na verdade números, Go também não suporta convertê-las diretamente em strings, mas podemos adicionar métodos ao tipo personalizado para retornar sua representação em string, basta implementar a interface 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 ""
}

Assim temos uma implementação simples de enumeração. Você também pode usar a ferramenta oficial Stringer para gerar enumerações automaticamente.

No entanto, tem as seguintes desvantagens

  • Não é seguro em termos de tipo, porque Season é um tipo personalizado, outros números podem ser convertidos para este tipo através de conversão forçada

    go
    Season(6)
  • Verboso, a representação em string precisa ser implementada manualmente

  • Capacidade de expressão fraca, porque const só suporta tipos de dados básicos, então estes valores de enumeração só podem ser representados por strings e números

Por que não há suporte a enumeração em nível de linguagem é algo que o autor não consegue entender, acredito que isso seria mais vantajoso que desvantajoso.

Golang por www.golangdev.cn edit