Menu
Coddy logo textTech

Campi esportati e non esportati

Fa parte della sezione Programmazione orientata agli oggetti del percorso GO di Coddy. Lezione 47 di 107.

In Go, l’incapsulamento a livello di struct è controllato dalle maiuscole e minuscole dei nomi dei campi. Questa semplice regola determina se i campi possono essere acceduti dall’esterno del package in cui è definita la struct.

I campi che iniziano con una lettera maiuscola sono esportati: accessibili da qualsiasi pacchetto. I campi che iniziano con una lettera minuscola sono non esportati: accessibili solo all'interno dello stesso pacchetto:

// Nel pacchetto "user"
type User struct {
    Name     string  // Esportato - accessibile ovunque
    Email    string  // Esportato - accessibile ovunque
    password string  // Non esportato - accessibile solo nel pacchetto "user"
    age      int     // Non esportato - accessibile solo nel pacchetto "user"
}

Quando un altro pacchetto importa e usa questa struct, può interagire solo con i campi esportati:

// Nel package "main"
import "user"

func main() {
    u := user.User{
        Name:  "Alice",      // funziona
        Email: "a@mail.com", // funziona
        // password: "secret", // errore di compilazione: campo sconosciuto
    }
    
    fmt.Println(u.Name)     // funziona
    // fmt.Println(u.password) // errore di compilazione: impossibile accedere a un campo non esportato
}

Questo meccanismo protegge i dati sensibili e i dettagli interni dell’implementazione. Il campo password non può essere letto o modificato direttamente dall’esterno del pacchetto, costringendo il resto del codice a usare i metodi che fornisci. Questo è l’approccio di Go per ottenere l’occultamento dei dati: un principio fondamentale dell’incapsulamento nella programmazione orientata agli oggetti.

challenge icon

Sfida

Facile

Costruiamo un sistema di conto bancario che dimostri l'incapsulamento tramite campi esportati e non esportati. Creerai un package che protegge i dati finanziari sensibili ed espone informazioni pubbliche sicure.

Organizzerai il codice in due file:

  • account.go: Crea una struct BankAccount nel package main che modella un conto bancario reale con un'adeguata protezione dei dati:
    • HolderName (esportato) - il nome del titolare del conto, sicuro da mostrare pubblicamente
    • AccountType (esportato) - il tipo di conto (ad es., "Savings", "Checking")
    • balance (non esportato) - il saldo effettivo, che deve essere protetto
    • pin (non esportato) - il PIN del conto, un dato altamente sensibile
    Aggiungi una funzione costruttore NewBankAccount che accetta il nome del titolare, il tipo di conto, il saldo iniziale e il PIN, quindi restituisce un puntatore a un nuovo BankAccount. Aggiungi anche un metodo GetPublicInfo() string che restituisce il formato: Account: [HolderName] ([AccountType])
  • main.go: Leggi i dettagli del conto dall'input, crea un BankAccount usando il costruttore e dimostra l'incapsulamento. Stampa le informazioni pubbliche usando il metodo, quindi accedi direttamente a ciascun campo esportato e stampalo su una riga separata. I campi non esportati (balance e pin) sono protetti. Puoi impostarli solo tramite il costruttore.

Verranno forniti i seguenti input:

  • Riga 1: Nome del titolare del conto
  • Riga 2: Tipo di conto
  • Riga 3: Saldo iniziale (come float)
  • Riga 4: Codice PIN

Ad esempio, dati Alice Johnson, Savings, 5000.50 e 1234, l'output dovrebbe essere:

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

Nota che il saldo e il PIN non compaiono mai nell'output: sono nascosti in modo sicuro all'interno della struct e sono accessibili solo all'interno del package. Questo è l'incapsulamento in azione: i dati sensibili sono protetti mentre le informazioni pubbliche restano accessibili.

Provalo tu

package main

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

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

	// Leggi il nome del titolare del conto
	holderName, _ := reader.ReadString('\n')
	holderName = strings.TrimSpace(holderName)

	// Leggi il tipo di conto
	accountType, _ := reader.ReadString('\n')
	accountType = strings.TrimSpace(accountType)

	// Leggi il saldo iniziale
	balanceStr, _ := reader.ReadString('\n')
	balanceStr = strings.TrimSpace(balanceStr)
	balance, _ := strconv.ParseFloat(balanceStr, 64)

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

	// TODO: Crea un nuovo BankAccount usando il costruttore
	// account := NewBankAccount(...)

	// TODO: Stampa le informazioni pubbliche usando il metodo GetPublicInfo()

	// TODO: Stampa il nome del titolare accedendo direttamente al campo esportato
	// fmt.Println("Holder:", ...)

	// TODO: Stampa il tipo di conto accedendo direttamente al campo esportato
	// fmt.Println("Type:", ...)

	// Nota: balance e pin non sono esportati: non è possibile accedervi direttamente qui
	// They are safely encapsulated within the struct

	_ = balance // Remove this line when you use balance
	_ = pin     // Remove this line when you use pin
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Go online