Menu
Coddy logo textTech

Campos Exportados vs Não Exportados

Parte da seção Programação Orientada a Objetos do Journey de GO da Coddy — lição 47 de 107.

Em Go, o encapsulamento no nível da struct é controlado pela capitalização dos nomes dos campos. Essa regra simples determina se os campos podem ser acessados de fora do pacote onde a struct está definida.

Campos que começam com uma letra maiúscula são exportados—acessíveis a partir de qualquer pacote. Campos que começam com uma letra minúscula não são exportados—acessíveis apenas dentro do mesmo pacote:

// No pacote "user"
type User struct {
    Name     string  // Exportado - acessível em qualquer lugar
    Email    string  // Exportado - acessível em qualquer lugar
    password string  // Não exportado - acessível apenas no pacote "user"
    age      int     // Não exportado - acessível apenas no pacote "user"
}

Quando outro pacote importa e usa esta struct, ele só pode interagir com campos exportados:

// No pacote "main"
import "user"

func main() {
    u := user.User{
        Name:  "Alice",      // funciona
        Email: "a@mail.com", // funciona
        // password: "secret", // erro de compilação: campo desconhecido
    }
    
    fmt.Println(u.Name)     // funciona
    // fmt.Println(u.password) // erro de compilação: não é possível referenciar um campo não exportado
}

Este mecanismo protege dados sensíveis e detalhes de implementação interna. O campo password não pode ser lido ou modificado diretamente de fora do pacote, forçando outros códigos a usarem métodos que você fornece. Esta é a abordagem do Go para alcançar a ocultação de dados — um princípio fundamental do encapsulamento na programação orientada a objetos.

challenge icon

Desafio

Fácil

Vamos construir um sistema de conta bancária que demonstra o encapsulamento por meio de campos exportados e não exportados. Você criará um pacote que protege dados financeiros sensíveis enquanto expõe informações públicas seguras.

Você organizará seu código em dois arquivos:

  • account.go: Crie uma struct BankAccount no pacote main que modele uma conta bancária real com a devida proteção de dados:
    • HolderName (exportado) - o nome do titular da conta, seguro para exibição pública
    • AccountType (exportado) - o tipo de conta (ex: "Savings", "Checking")
    • balance (não exportado) - o saldo real, que deve ser protegido
    • pin (não exportado) - o PIN da conta, um dado altamente sensível
    Adicione uma função construtora NewBankAccount que receba o nome do titular, o tipo de conta, o saldo inicial e o PIN, e retorne um ponteiro para um novo BankAccount. Adicione também um método GetPublicInfo() string que retorne o formato: Account: [HolderName] ([AccountType])
  • main.go: Leia os detalhes da conta da entrada, crie um BankAccount usando o construtor e demonstre o encapsulamento. Imprima as informações públicas usando o método e, em seguida, acesse e imprima diretamente cada campo exportado em linhas separadas. Os campos não exportados (balance e pin) estão protegidos — você só pode defini-los através do construtor.

As seguintes entradas serão fornecidas:

  • Linha 1: Nome do titular da conta
  • Linha 2: Tipo de conta
  • Linha 3: Saldo inicial (como um float)
  • Linha 4: Código PIN

Por exemplo, dados Alice Johnson, Savings, 5000.50 e 1234, sua saída deve ser:

Account: Alice Johnson (Savings)
Holder: Alice Johnson
Type: Savings

Observe que o saldo e o PIN nunca aparecem na saída — eles estão ocultos com segurança dentro da struct, acessíveis apenas dentro do pacote. Isso é o encapsulamento em ação: dados sensíveis são protegidos enquanto as informações públicas permanecem acessíveis.

Folha de consulta

Em Go, o encapsulamento é controlado pela capitalização dos nomes dos campos em structs:

  • Campos em maiúsculo são exportados (acessíveis de qualquer pacote)
  • Campos em minúsculo não são exportados (acessíveis apenas dentro do mesmo pacote)
type User struct {
    Name     string  // Exportado - acessível em qualquer lugar
    Email    string  // Exportado - acessível em qualquer lugar
    password string  // Não exportado - acessível apenas no mesmo pacote
    age      int     // Não exportado - acessível apenas no mesmo pacote
}

Ao usar uma struct de outro pacote, apenas os campos exportados são acessíveis:

import "user"

func main() {
    u := user.User{
        Name:  "Alice",      // funciona
        Email: "a@mail.com", // funciona
        // password: "secret", // erro de compilação: campo desconhecido
    }
    
    fmt.Println(u.Name)     // funciona
    // fmt.Println(u.password) // erro de compilação: não é possível referenciar um campo não exportado
}

Este mecanismo protege dados sensíveis e detalhes de implementação interna, forçando o código externo a usar os métodos fornecidos para acesso.

Experimente você mesmo

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// Ler o nome do titular da conta
	holderName, _ := reader.ReadString('\n')
	holderName = strings.TrimSpace(holderName)

	// Ler o tipo de conta
	accountType, _ := reader.ReadString('\n')
	accountType = strings.TrimSpace(accountType)

	// Ler o saldo inicial
	balanceStr, _ := reader.ReadString('\n')
	balanceStr = strings.TrimSpace(balanceStr)
	balance, _ := strconv.ParseFloat(balanceStr, 64)

	// Ler o PIN
	pinStr, _ := reader.ReadString('\n')
	pin := strings.TrimSpace(pinStr)

	// TODO: Criar um novo BankAccount usando o construtor
	// account := NewBankAccount(...)

	// TODO: Imprimir as informações públicas usando o método GetPublicInfo()

	// TODO: Imprimir o nome do titular acessando diretamente o campo exportado
	// fmt.Println("Holder:", ...)

	// TODO: Imprimir o tipo de conta acessando diretamente o campo exportado
	// fmt.Println("Type:", ...)

	// Note: balance e pin não são exportados - eles não podem ser acessados diretamente aqui
	// Eles estão encapsulados com segurança dentro da struct

	_ = balance // Remova esta linha quando você usar balance
	_ = pin     // Remova esta linha quando você usar pin
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos