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 pelo uso de maiúsculas ou minúsculas nos nomes dos campos. Essa regra simples determina se os campos podem ser acessados de fora do pacote onde a struct é 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 são não exportados: acessíveis apenas dentro do mesmo pacote:

// No pacote "user"
type User struct {
    Name     string  // Exportado - acessível em todos os lugares
    Email    string  // Exportado - acessível em todos os lugares
    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 essa estrutura, 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 campo não exportado
}

Esse mecanismo protege dados confidenciais e detalhes internos da implementação. O campo password não pode ser lido ou modificado diretamente de fora do pacote, obrigando outro código a usar os métodos que você fornece. Essa é a abordagem do Go para alcançar a ocultação de dados: um princípio fundamental da encapsulação na programação orientada a objetos.

challenge icon

Desafio

Fácil

Vamos criar um sistema de conta bancária que demonstra encapsulamento por meio de campos exportados e não exportados. Você criará um pacote que protege dados financeiros confidenciais 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 proteção adequada dos dados:
    • HolderName (exportado) - o nome do titular da conta, seguro para exibição pública
    • AccountType (exportado) - o tipo de conta (por exemplo, "Savings", "Checking")
    • balance (não exportado) - o saldo real, que deve ser protegido
    • pin (não exportado) - o PIN da conta, um dado altamente confidencial
    Adicione uma função construtora NewBankAccount que receba o nome do titular, o tipo de conta, o saldo inicial e o PIN, e então retorne um ponteiro para uma nova BankAccount. Adicione também um método GetPublicInfo() string que retorne o formato: Account: [HolderName] ([AccountType])
  • main.go: Leia os dados da conta da entrada, crie uma BankAccount usando a função construtora 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) são protegidos. Você só pode defini-los por meio da função construtora.

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 deverá ser:

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

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

Experimente você mesmo

package main

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

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

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

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

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

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

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

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

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

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

	// Note: balance e pin são unexported - 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

Pratique por conta própria: Compilador de Go online