Médio Go

Usando pacote internal

Enunciado

Crie um módulo exemplo.com/loja com um pacote internal/precos que exporte a função ComDesconto(valor float64) float64 (aplicando 10% de desconto). No main.go, importe e use essa função para calcular o preço de um produto de R$ 100,00. Imprima o valor com desconto formatado com duas casas decimais.

Requisitos

  • O pacote precos deve estar dentro de internal/.
  • A função ComDesconto deve ser exportada e retornar o valor com 10% de desconto.
  • O main.go deve importar exemplo.com/loja/internal/precos.
  • A saída deve ser exatamente Preço com desconto: 90.00.

Código inicial

// main.go
package main

import (
	"fmt"
	// importe o pacote internal/precos
)

func main() {
	// use precos.ComDesconto(100.0) e imprima com 2 casas decimais
	fmt.Println("Preço com desconto: 0.00") // substitua
}

Saída esperada

Preço com desconto: 90.00
Ver dica

A função deve retornar valor * 0.9. Use fmt.Printf com %.2f para formatar.

Mostrar solução
// go.mod
module exemplo.com/loja

go 1.22
// internal/precos/precos.go
package precos

// ComDesconto aplica 10% de desconto ao valor.
// Exportada (maiúscula) e acessível apenas dentro do módulo loja.
func ComDesconto(valor float64) float64 {
	return valor * 0.9
}
// main.go
package main

import (
	"fmt"
	"exemplo.com/loja/internal/precos"
)

func main() {
	preco := precos.ComDesconto(100.0)
	fmt.Printf("Preço com desconto: %.2f\n", preco)
}

Passo a passo

  1. Criamos o módulo com go mod init exemplo.com/loja.
  2. Dentro da pasta internal/precos, criamos precos.go com package precos.
  3. A função ComDesconto é exportada (inicial maiúscula) e multiplica o valor por 0.9, aplicando 10% de desconto.
  4. No main.go, importamos o pacote usando o caminho completo exemplo.com/loja/internal/precos.
  5. Chamamos precos.ComDesconto(100.0) e armazenamos em preco.
  6. Usamos fmt.Printf com %.2f para imprimir o valor com duas casas decimais.

Por que funciona

O diretório internal é especial: pacotes dentro dele só podem ser importados por código que esteja na mesma árvore de diretórios (ou seja, dentro do módulo exemplo.com/loja). Como o main.go está na raiz do módulo, ele pode importar internal/precos. Se outro módulo tentasse importar, o compilador rejeitaria. Isso protege código interno de ser usado externamente.

Erros comuns

  • Tentar importar internal de fora: se você criar outro módulo e tentar import "exemplo.com/loja/internal/precos", o compilador dá erro use of internal package not allowed. A solução é não usar internal para APIs públicas.
  • Função não exportada: func comDesconto(...) com minúscula não é acessível de main. Erro: undefined: precos.ComDesconto.
  • Formatação incorreta: usar fmt.Println(preco) imprime 90 (sem casas decimais) em vez de 90.00. Use fmt.Printf com %.2f.

Outra forma de resolver

Se a função não precisasse ser restrita ao módulo, poderia ficar em um pacote normal (sem internal). O internal é útil justamente para esconder detalhes de implementação.

Saída esperada

Preço com desconto: 90.00