Menu
Coddy logo textTech

Campos exportados vs. no exportados

Parte de la sección Programación Orientada a Objetos del Journey de GO de Coddy. Lección 47 de 107.

En Go, la encapsulación a nivel de estructura se controla mediante el uso de mayúsculas y minúsculas en los nombres de los campos. Esta sencilla regla determina si se puede acceder a los campos desde fuera del paquete en el que se define la estructura.

Los campos que comienzan con una letra mayúscula son exportados: accesibles desde cualquier paquete. Los campos que comienzan con una letra minúscula son no exportados: solo accesibles dentro del mismo paquete:

// En el paquete "user"
type User struct {
    Name     string  // Exportado - accesible en todas partes
    Email    string  // Exportado - accesible en todas partes
    password string  // No exportado - solo accesible en el paquete "user"
    age      int     // No exportado - solo accesible en el paquete "user"
}

Cuando otro paquete importa y utiliza esta estructura, solo puede interactuar con campos exportados:

// En el paquete "main"
import "user"

func main() {
    u := user.User{
        Name:  "Alice",      // funciona
        Email: "a@mail.com", // funciona
        // password: "secret", // error de compilación: campo desconocido
    }
    
    fmt.Println(u.Name)     // funciona
    // fmt.Println(u.password) // error de compilación: no se puede referir a un campo no exportado
}

Este mecanismo protege los datos confidenciales y los detalles de implementación internos. El campo password no se puede leer ni modificar directamente desde fuera del paquete, lo que obliga a otro código a utilizar los métodos que proporcionas. Este es el enfoque de Go para lograr la ocultación de datos: un principio fundamental de la encapsulación en la programación orientada a objetos.

challenge icon

Desafío

Fácil

Construyamos un sistema de cuentas bancarias que demuestre la encapsulación mediante campos exportados y no exportados. Crearás un paquete que proteja los datos financieros confidenciales y, al mismo tiempo, exponga información pública segura.

Organizarás tu código en dos archivos:

  • account.go: Crea una estructura BankAccount en el paquete main que modele una cuenta bancaria real con la protección adecuada de datos:
    • HolderName (exportado): el nombre del titular de la cuenta, seguro para mostrar públicamente
    • AccountType (exportado): el tipo de cuenta (por ejemplo, "Savings", "Checking")
    • balance (no exportado): el saldo real, que debe estar protegido
    • pin (no exportado): el PIN de la cuenta, un dato altamente confidencial
    Añade una función constructora NewBankAccount que reciba el nombre del titular, el tipo de cuenta, el saldo inicial y el PIN, y después devuelva un puntero a un nuevo BankAccount. Añade también un método GetPublicInfo() string que devuelva el formato: Account: [HolderName] ([AccountType])
  • main.go: Lee los detalles de la cuenta desde la entrada, crea un BankAccount usando la función constructora y demuestra la encapsulación. Imprime la información pública mediante el método y, después, accede directamente a cada campo exportado y lo imprime en líneas separadas. Los campos no exportados (balance y pin) están protegidos. Solo puedes establecerlos mediante la función constructora.

Se proporcionarán las siguientes entradas:

  • Línea 1: Nombre del titular de la cuenta
  • Línea 2: Tipo de cuenta
  • Línea 3: Saldo inicial (como un número de tipo float)
  • Línea 4: Código PIN

Por ejemplo, dadas Alice Johnson, Savings, 5000.50 y 1234, tu salida debería ser:

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

Observa que el saldo y el PIN nunca aparecen en la salida: están ocultos de forma segura dentro de la estructura y solo son accesibles dentro del paquete. Esto es la encapsulación en acción: los datos confidenciales están protegidos mientras la información pública sigue siendo accesible.

Pruébalo tú mismo

package main

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

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

	// Lee el nombre del titular de la cuenta
	holderName, _ := reader.ReadString('\n')
	holderName = strings.TrimSpace(holderName)

	// Lee el tipo de cuenta
	accountType, _ := reader.ReadString('\n')
	accountType = strings.TrimSpace(accountType)

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

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

	// TODO: Crea un nuevo BankAccount usando el constructor
	// account := NewBankAccount(...)

	// TODO: Imprime la información pública usando el método GetPublicInfo()

	// TODO: Imprime el nombre del titular accediendo directamente al campo exportado
	// fmt.Println("Holder:", ...)

	// TODO: Imprime el tipo de cuenta accediendo directamente al campo exportado
	// fmt.Println("Type:", ...)

	// Note: balance y pin no están exportados - no se puede acceder a ellos directamente aquí
	// Están encapsulados de forma segura dentro de la struct

	_ = balance // Elimina esta línea cuando uses balance
	_ = pin     // Elimina esta línea cuando uses pin
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de Go online