Conversão de tipos em constantes?

👨🏻‍💻 Olá pessoal!

Hoje vamos falar um pouco sobre “constantes”. Para começar veja abaixo o seguinte código:

package main
import (
	"fmt"
)

func main() {
	const c = 3
	fmt.Printf("c:  %v %T\n", c, c)
}

No exemplo acima, criamos uma função main e declaramos uma constante de nome c atribuindo à mesma o valor 3.

Constantes não podem ser vazias, pois como o próprio nome diz, elas são imutáveis. Logo, se criassemos uma constante vazia e depois fossemos atribuir valor, ela não seria imutável por natureza.

No caso de Go, ao realizar a atribuição, o tipo da constante é inferido de acordo com o valor que foi atribuído à mesma.

No código acima foi atribuído o valor 3 então, pela inferência de tipos, c é uma constante do tipo inteiro.

A prova disso pode ser obtida quando solicitamos através de um Printf o retorno do tipo, usando %T.

fmt.Printf("c: %v %T\n", c, c)

Vamos adicionar uma nova linha ao nosso código.Agora pense um pouco e responda:

Sendo c definido como constante do tipo int, a operação realizada no código abaixo é permitida?

package main

import (
	"fmt"
)

func main() {
	const c = 3
	fmt.Printf("c:  %v %T\n", c, c)
	fmt.Printf("c: %v", c + 3.333)
}

Surpreso com o resultado? Então vamos à próxima pergunta:

Qual é tipo de c após a operação?

Para saber, vamos acrescentar um %T à nossa nova linha de código.

package main
import (
	"fmt"
)

func main() {
	const c = 3
	fmt.Printf("c:  %v %T\n", c, c)
	fmt.Printf("c: %v %T", c + 3.333,c)
}

Certamente você deve ter ficado ainda mais intrigado com o resultado, mas nosso experimento ainda não está completo.

Finalmente, vamos acrescentar mais uma linha ao nosso código:fmt.Printf("c: %v %T\n", c, c)

O programa completo vai ficar assim:

package main
import (
	"fmt"
)

func main() {
	const c = 3
	fmt.Printf("c:  %v %T\n", c, c)
	fmt.Printf("c: %v %T", c + 3.333,c)
	fmt.Printf("c:  %v %T\n", c, c)
}

Deu nó na cabeça?

Vamos às explicações

Em Go, ao declarar uma constante, ela infere seu tipo de acordo com o valor atribuído à mesma, todavia, essa constante pode em algumas operações se comportar como se fosse de outro tipo, principalmente quando não há perda ou truncagem de informação.

No nosso caso, c é um int, porém uma conversão para float é perfeitament possível sem perda de informação significativa.

Nesse caso, o compilador é inteligente o suficiente para entender isso e realiza a conversão de tipos em tempo de execução para a operação.

Ou seja, embora c seja um int, para uma operação de adição com um float o compilador realiza a conversão durante a execução sem gerar erro.

Mas é preciso lembrar que c é uma constante, logo imutável. Seu valor armazenado na memória continua sendo do tipo inteiro, como pudemos provar em nossa última linha de código.

Espero que tenham gostado e até a próxima.