Fundamentos de Constantes em Go

GolangBeginner
Pratique Agora

Introdução

Nas lições anteriores, aprendemos sobre variáveis em Go. Nesta aula, vamos explorar o conceito de constantes, como utilizá-las e por que elas são importantes. Vamos mergulhar no mundo das constantes.

Pontos de Conhecimento:

  • O que são constantes
  • Declaração de constantes
  • O gerador de constantes iota
  • Utilização de constantes

O Que São Constantes?

De forma simples, uma constante é um valor que é declarado e não pode ser modificado durante a execução do programa. As constantes permitem que o compilador conheça seus valores antes da execução do programa, ainda na fase de compilação.

As declarações de constantes podem ter valores específicos atribuídos a elas. Sua sintaxe é semelhante à das variáveis, mas uma vez que o valor de uma constante é declarado, ele não pode ser alterado.

As constantes são úteis quando você deseja declarar um valor que deve permanecer fixo, como o endereço de um site ou um valor matemático específico, como o π (Pi).

Declaração de Constantes

A declaração de constantes é muito parecida com a de variáveis. A palavra-chave var é substituída pela palavra-chave const.

Nota: As constantes devem obrigatoriamente receber um valor no momento em que são declaradas.

Em Go, todas as variáveis devem ser utilizadas após serem definidas, mas as constantes são uma exceção. Mesmo que não sejam usadas, o compilador não gerará erro.

A sintaxe para declarar uma constante é a seguinte:

const name [type] = value

name é o nome da constante. type é o tipo de dado da constante, mas pode ser omitido porque o Go consegue inferi-lo automaticamente. O value ao final é o valor atribuído à constante.

Note que apenas os seguintes tipos podem ser usados em declarações de constantes:

  • Tipos inteiros
  • Tipos de ponto flutuante
  • Tipos complexos
  • Tipos booleanos
  • Tipos de string

Vamos ver um exemplo. Crie um novo arquivo chamado const.go no diretório ~/project:

touch ~/project/const.go

Insira o seguinte código em const.go:

package main

import "fmt"

// Declara uma única constante
const labex string = "LabEx" // especifica explicitamente o tipo como string
const labs = "LABS"    // inferido automaticamente como string pelo compilador

// Declara múltiplas constantes
const (
    hangzhou, chengdu = "HANGZHOU", "CHENGDU"
    monday, tuesday, wednesday = "MONDAY", "TUESDAY", "WEDNESDAY"
)

func main() {
    fmt.Printf("The type of labex is: %T, and its value is %s\n", labex, labex)
    fmt.Printf("The type of labs is: %T, and its value is %s\n", labs, labs)

    fmt.Println()

    fmt.Println(hangzhou, chengdu)
    fmt.Println(monday, tuesday, wednesday)
}
go run ~/project/const.go

Após executar o programa, a saída será:

The type of labex is: string, and its value is LabEx
The type of labs is: string, and its value is LABS

HANGZHOU CHENGDU
MONDAY TUESDAY WEDNESDAY

Aqui, demonstramos a declaração de constantes únicas e múltiplas. Ao declarar várias constantes, recomenda-se o uso de parênteses para melhor organização.

No programa, mostramos apenas constantes do tipo string. No entanto, constantes podem assumir outros tipos, como inteiros e booleanos.

Ao declarar múltiplas constantes usando parênteses, se uma constante não for inicializada, ela herdará o valor da constante anterior.

Insira o seguinte código em const.go:

package main

import "fmt"

const (
    monday    = "MONDAY"
    tuesday   = "TUESDAY"
    wednesday = "WEDNESDAY"
    thursday
    friday
)

func main() {
    fmt.Println(monday, tuesday, wednesday, thursday, friday)
}
go run ~/project/const.go

A saída será:

MONDAY TUESDAY WEDNESDAY WEDNESDAY WEDNESDAY

Neste caso, thursday e friday não possuem valores explícitos. De acordo com as regras do Go, quando uma constante não é inicializada explicitamente em um bloco const, ela herda o valor da constante anterior. Portanto:

  • thursday herda o valor de wednesday.
  • friday também herda o valor de wednesday.

Esse comportamento permite escrever códigos mais concisos, mas pode levar a resultados inesperados se você não estiver ciente dessa regra.

Se você quiser que thursday e friday tenham valores distintos, deve atribuí-los explicitamente:

const (
    monday    = "MONDAY"
    tuesday   = "TUESDAY"
    wednesday = "WEDNESDAY"
    thursday  = "THURSDAY"
    friday    = "FRIDAY"
)

Isso produzirá a saída esperada:

MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY

O Gerador de Constantes iota

Além de declarar constantes uma a uma, podemos usar o iota para declará-las em lotes de forma sequencial. Vamos ver um exemplo. Escreva o seguinte código no arquivo const.go:

package main

import "fmt"

const (
    monday    = iota // valor inicial é 0
    tuesday   = iota // incrementa 1 a cada linha
    wednesday = iota
    thursday  = iota
    friday    = iota
)

func main() {
    fmt.Println(monday, tuesday, wednesday, thursday, friday)
}
go run ~/project/const.go

A saída será:

0 1 2 3 4

Ao usar iota, o valor inicial é 0 e ele é incrementado em 1 para cada item subsequente no bloco de constantes.

Após o primeiro item ser declarado com iota, as constantes seguintes não precisam de atribuição explícita. O código abaixo também funcionará corretamente:

package main

import "fmt"

const (
    monday    = iota // 0
    tuesday          // 1
    wednesday        // 2
    thursday         // 3
    friday           // 4
)

func main() {
    fmt.Println(monday, tuesday, wednesday, thursday, friday)
}

E se quisermos pular um valor específico? Nesse caso, podemos usar o identificador em branco (underscore). O código a seguir pula o valor correspondente à quarta-feira:

package main

import "fmt"

const (
    monday  = iota // 0
    tuesday        // 1
    _
    thursday // 3
    friday   // 4
)

func main() {
    fmt.Println(monday, tuesday, thursday, friday)
}
go run ~/project/const.go

Como você pode ver, a saída será:

0 1 3 4

O operador iota também pode ser utilizado em operações aritméticas. Insira o seguinte código em const.go:

package main

import "fmt"

const (
    a = iota     // 0
    b = iota * 3 // 1 * 3
    c = iota + 4 // 2 + 4
)

const (
    B  = 1 << (iota * 10) // equivale a 1 << (0 * 10)
    KB                    // 1024
    MB                    // 1048576
)

func main() {
    fmt.Println(a, b, c)
    fmt.Println(B, KB, MB)
}
go run ~/project/const.go

A saída será:

0 3 6
1 1024 1048576

No primeiro bloco de declarações, usamos iota para realizar operações aritméticas simples.

No segundo bloco, utilizamos iota com o operador de deslocamento de bits à esquerda << para expressar os valores de 1 KB e 1 MB em termos de bytes (B). Por exemplo, 1 KB é igual a 1024B, e 1 MB é igual a 1024 * 1024, que resulta em 1048576B.

Desafio

Agora vamos reforçar o que aprendemos. Crie um novo arquivo chamado iota.go e use iota e constantes para exibir os valores de 1GB e 1TB em termos de bytes (B).

Requisitos:

  1. Não exiba diretamente os números convertidos. Use iota para realizar a conversão.
  2. O arquivo iota.go deve estar localizado no diretório ~/project.

Dica: Você pode se basear no código da seção sobre "iota".

O formato de saída esperado é:

1GB is equal to 1073741824B
1TB is equal to 1099511627776B

Resumo

Vamos revisar o que aprendemos nesta lição:

  • Constantes não podem ser modificadas após serem declaradas.
  • Constantes são declaradas usando a palavra-chave const.
  • Ao declarar múltiplas constantes, é preferível utilizar parênteses.
  • O gerador de constantes iota pode ser usado para criar enumerações e sequências.
  • O iota também pode ser integrado em operações aritméticas.

Nesta aula, exploramos as constantes e introduzimos o gerador iota. Strings, inteiros, números de ponto flutuante e constantes formam a base dos tipos de dados em Go.

✨ Verificar Solução e Praticar