Médio Go

Escopo e shadowing

Enunciado

Crie um programa que declare uma variável x no escopo da função main com valor 10. Dentro de um bloco {}, declare outra variável x com valor 20 e imprima ambas. Depois do bloco, imprima novamente a variável externa para mostrar que ela não foi alterada.

Requisitos

  • Declarar x externa com := e valor 10.
  • Dentro de um bloco {}, declarar x interna com := e valor 20.
  • Imprimir os valores dentro e fora do bloco, mostrando que a externa permanece 10.
  • Usar comentários para indicar qual x está sendo impresso.

Código inicial

package main

import "fmt"

func main() {
	// declare x externo
	// bloco interno
	// imprima x externo novamente
}

Saída esperada

x externo: 10
x interno: 20
x externo depois: 10
Ver dica

O := dentro do bloco cria uma nova variável, não altera a de fora. Use fmt.Println com rótulos diferentes.

Mostrar solução
package main

import "fmt"

func main() {
	x := 10
	fmt.Println("x externo:", x)

	{
		x := 20 // shadowing: nova variável x
		fmt.Println("x interno:", x)
	}

	fmt.Println("x externo depois:", x)
}

Passo a passo

  1. x := 10 declara uma variável x no escopo da função main.
  2. Imprimimos x externo: 10.
  3. Abrimos um bloco {} e dentro dele usamos x := 20. Isso cria uma nova variável x, que sombreia a externa apenas dentro desse bloco.
  4. Imprimimos x interno: 20 — refere-se à variável interna.
  5. Fechamos o bloco. A variável interna deixa de existir.
  6. Imprimimos novamente x — agora refere-se à variável externa, que continua valendo 10.

Por que funciona

O escopo em Go é léxico: uma variável é visível apenas dentro do bloco onde foi declarada. Quando você declara uma variável com o mesmo nome em um bloco interno, ocorre shadowing: a variável interna esconde a externa enquanto o bloco estiver ativo. Ao sair do bloco, a externa volta a ser visível. Isso é útil para evitar poluição de nomes, mas requer atenção para não modificar a variável errada.

Erros comuns

  • Usar = em vez de := dentro do bloco: x = 20 alteraria a variável externa, não criaria uma nova. O resultado seria x externo depois: 20.
  • Declarar x com var dentro do bloco: var x int = 20 também cria uma nova variável, mas é mais verboso; o efeito de shadowing é o mesmo.
  • Esquecer as chaves: sem {}, não há novo escopo; x := 20 no mesmo escopo causaria erro de redeclaração.

Outra forma de resolver

Se a intenção fosse modificar a variável externa, usaríamos x = 20 (sem :). Mas o enunciado pede shadowing, então a solução acima é a correta.

Saída esperada

x externo: 10
x interno: 20
x externo depois: 10