Skip to content

Variáveis do Go

Uma variável é um local de armazenamento usado para guardar um valor, permitindo que o valor armazenado mude dinamicamente durante a execução. Cada vez que uma variável é declarada, um bloco de memória é alocado para armazenar o valor do tipo correspondente, vá para Manual de Referência - Variáveis para ver mais detalhes.

Declaração

Em Go, a declaração de tipo é pós-fixada, a declaração de variáveis usa a palavra-chave var, o formato é var nomeDaVariável nomeDoTipo, as regras de nomenclatura do nome da variável devem seguir as regras de nomenclatura de identificadores.

go
var intNum int
var str string
var char byte

Quando for declarar múltiplas variáveis do mesmo tipo, pode escrever o tipo apenas uma vez

go
var numA, numB, numC int

Quando for declarar múltiplas variáveis de tipos diferentes, pode usar () para agrupar, pode haver múltiplos ().

go
var (
  name    string
  age     int
  address string
)

var (
  school string
  class int
)

Se uma variável for apenas declarada sem ser atribuída, o valor armazenado na variável é o valor zero do tipo correspondente.

Atribuição

A atribuição usa o operador =, por exemplo

go
var name string
name = "jack"

Também pode atribuir diretamente ao declarar

go
var name string = "jack"

Ou assim também funciona

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

A segunda forma exige especificar o tipo a cada vez, pode-se usar o açúcar sintático fornecido oficialmente: inicialização curta de variável, pode omitir a palavra-chave var e o tipo pós-fixado, o tipo específico é inferido pelo compilador.

go
name := "jack" // variável do tipo string

Embora não precise especificar o tipo, em atribuições subsequentes, o tipo deve permanecer consistente, o código abaixo não pode compilar.

a := 1
a = "1"

Também需要注意, a inicialização curta de variável não pode usar nil, porque nil não pertence a nenhum tipo, o compilador não pode inferir seu tipo.

go
name := nil // não pode compilar

A declaração curta de variável pode inicializar em lote

go
name, age := "jack", 1

A declaração curta de variável não pode ser usada em uma variável já existente, por exemplo

go
// Exemplo errado
var a int
a := 1

// Exemplo errado
a := 1
a := 2

Mas há uma exceção, que é ao atribuir a uma variável antiga e ao mesmo tempo declarar uma nova variável, por exemplo

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

Este código pode compilar, a variável a é reatribuída, enquanto b é recém-declarada.

Em Go, há uma regra, que todas as variáveis em funções devem ser usadas, por exemplo, o código abaixo apenas declarou a variável, mas não a usou

go
func main() {
  a := 1
}

Então na compilação vai dar erro, avisando que a variável foi declarada mas não usada

a declared and not used

Esta regra se aplica apenas a variáveis dentro de funções, para variáveis de nível de pacote fora de funções não há essa limitação, o código abaixo pode compilar.

go
var a = 1

func main() {

}

Anônimo

Use sublinhado para indicar que não precisa de uma certa variável

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

Por exemplo, a função os.Open tem dois valores de retorno, queremos apenas o primeiro, não o segundo, pode escrever assim

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

Variáveis não usadas não podem compilar, quando não precisar de uma certa variável, pode usar o sublinhado _ para substituir.

Troca

Em Go, se quiser trocar os valores de duas variáveis, não precisa usar ponteiros, pode usar o operador de atribuição para trocar diretamente, sintaticamente parece muito intuitivo, exemplo abaixo

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

Três variáveis também funcionam assim

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

Pense no código abaixo, é um pequeno trecho de código para calcular a sequência de Fibonacci, quais são os valores das três variáveis após o cálculo

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

A resposta é

1 1 1

Você pode se perguntar por que não é

1 1 2

Claramente a já recebeu o valor de b, por que o resultado de a+b ainda é 1? Go, ao fazer múltiplas operações de atribuição de variáveis, a ordem é primeiro calcular os valores depois atribuir, não da esquerda para a direita.

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

Você pode pensar que seria expandido para

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

Mas na verdade ele vai calcular os valores de a, b, c separadamente e depois atribuir a eles, é equivalente ao código abaixo

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

Quando envolve chamadas de função, este efeito é ainda mais óbvio, temos uma função sum que pode calcular o valor de retorno de dois números

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

Usando a função para somar dois números

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

O resultado não muda, ao calcular o valor de retorno da função sum, seus parâmetros ainda são 0 e 1

1 1 1

Então o código deve ser escrito separadamente assim.

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

Comparação

Há um pré-requisito importante para comparação entre variáveis, que é que os tipos devem ser iguais, Go não tem conversão implícita de tipos, código como o abaixo não pode compilar

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

O compilador vai informar que os tipos não são iguais

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

Então deve-se usar conversão explícita de tipo

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

Antes dos genéricos, as funções incorporadas min e max fornecidas pelo Go inicialmente só suportavam números de ponto flutuante, até a versão 1.21, Go finalmente reescreveu essas duas funções incorporadas com genéricos, agora pode usar a função min para comparar o valor mínimo

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

Use a função max para comparar o valor máximo

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

Seus parâmetros suportam todos os tipos comparáveis, os tipos comparáveis em Go são

  • Booleano
  • Numérico
  • String
  • Ponteiro
  • Canal (suporta apenas verificar se são iguais)
  • Array cujos elementos são tipos comparáveis (slices não são comparáveis) (suporta apenas verificar se são iguais) (suporta apenas comparação entre arrays do mesmo comprimento, porque o comprimento do array também é parte do tipo, e tipos diferentes não são comparáveis)
  • Struct cujos tipos de campos são todos comparáveis (suporta apenas verificar se são iguais)

Além disso, pode-se importar a biblioteca padrão cmp para comparar, mas suporta apenas parâmetros de tipos ordenados, em Go os tipos ordenados incorporados são apenas números e strings.

go
import "cmp"

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

Blocos de Código

Dentro de uma função, pode-se estabelecer um bloco de código através de chaves, os escopos de variáveis entre blocos de código são independentes entre si. Por exemplo, no código abaixo

go
func main() {
  a := 1

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

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

Sua saída é

2
3
1

As variáveis entre blocos são independentes entre si, não interferem umas com as outras, não podem ser acessadas, mas podem ser influenciadas pelo bloco pai.

go
func main() {
  a := 1

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

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

Sua saída é

2
1
1

Golang por www.golangdev.cn edit