La funzione `init`
Fa parte della sezione Logica e flusso del percorso GO di Coddy. Lezione 56 di 68.
La funzione init è una funzione speciale in Go che viene eseguita automaticamente quando viene importato un pacchetto. A differenza delle funzioni normali, non chiami direttamente init: Go la esegue per te durante il processo di inizializzazione del pacchetto.
Ecco come definisci una funzione init:
package mypackage
import "fmt"
func init() {
fmt.Println("Package mypackage is being initialized!")
}La funzione init ha alcune caratteristiche uniche: non accetta parametri, non restituisce valori e viene eseguita prima che inizi la funzione main. Questo la rende perfetta per impostare lo stato iniziale, registrare componenti o eseguire attività di configurazione una tantum necessarie al tuo pacchetto.
Quando importi un pacchetto che contiene una funzione init, ne vedrai subito gli effetti, anche se non usi nessuna delle funzioni esportate dal pacchetto. Ecco perché il modello di importazione con identificatore vuoto che hai imparato prima è così utile: ti permette di attivare l’inizializzazione di un pacchetto senza usare direttamente il suo codice.
Sfida
FacileCrea un sistema di inizializzazione dei pacchetti che mostri come le funzioni init vengono eseguite automaticamente quando i pacchetti vengono importati. Realizzerai un sistema di registrazione in cui pacchetti diversi si inizializzano autonomamente e tengono traccia della sequenza di avvio.
Riceverai due input:
- Una stringa contenente le definizioni dei pacchetti nel formato
"package1:message1,package2:message2,package3:message3"(ad es.,"database:Database connection pool initialized,cache:Cache system ready,logger:Logging system started") - Una stringa contenente le operazioni del programma principale nel formato
"operation1,operation2,operation3"(ad es.,"start_server,process_requests,shutdown")
Il tuo compito è:
- Analizzare il primo input suddividendolo in corrispondenza delle virgole per ottenere le singole definizioni dei pacchetti
- Per ogni definizione di pacchetto, suddividerla in corrispondenza dei due punti per ottenere il nome del pacchetto e il messaggio di inizializzazione
- Creare una slice globale chiamata
initLogper tenere traccia dei messaggi di inizializzazione - Creare una funzione chiamata
logInitche accetta un nome di pacchetto e un messaggio, quindi aggiunge il messaggio formattato"[INIT] [package_name]: [message]"alla sliceinitLog - Simulare l'inizializzazione dei pacchetti chiamando
logInitper ogni pacchetto nell'ordine in cui compare nell'input - Visualizzare l'intestazione della sequenza di inizializzazione:
"=== PACKAGE INITIALIZATION SEQUENCE ===" - Stampare ogni messaggio di inizializzazione dalla slice
initLog - Visualizzare l'intestazione del programma principale:
"=== MAIN PROGRAM EXECUTION ===" - Stampare:
"All packages initialized successfully" - Analizzare il secondo input suddividendolo in corrispondenza delle virgole per ottenere le singole operazioni
- Per ogni operazione del programma principale:
- Stampare:
"Executing: [operation]" - Aggiungere un messaggio al registro:
"[MAIN] Operation: [operation]" - Visualizzare il riepilogo dell'esecuzione:
"=== EXECUTION SUMMARY ===""Packages initialized: [number_of_packages]""Main operations executed: [number_of_operations]""Total log entries: [total_number_of_log_entries]"- Visualizzare il registro completo:
"=== COMPLETE EXECUTION LOG ==="- Stampare ogni voce del registro completo (sia i messaggi di inizializzazione sia le operazioni principali)
- Visualizzare il messaggio finale:
"Program execution completed - all init functions ran before main"
Usa il pacchetto strings per suddividere le stringhe di input e il pacchetto fmt per l'output formattato. Questa sfida mostra come le funzioni init vengano eseguite automaticamente durante l'importazione di un pacchetto e vengano sempre eseguite prima della funzione main, rendendole perfette per le attività di configurazione e inizializzazione dei pacchetti.
Provalo tu
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
// Slice globale per tenere traccia dei messaggi di inizializzazione
var initLog []string
func main() {
reader := bufio.NewReader(os.Stdin)
// Leggi l'input (bufio gestisce correttamente le righe con spazi)
packageDefs, _ := reader.ReadString('\n')
packageDefs = strings.TrimRight(packageDefs, "\r\n")
mainOps, _ := reader.ReadString('\n')
mainOps = strings.TrimRight(mainOps, "\r\n")
// TODO: Scrivi il tuo codice qui sotto
// 1. Analizza packageDefs suddividendolo in corrispondenza di "," per ottenere le singole voci dei pacchetti
// 2. Per ogni voce, suddividila in corrispondenza di ":" (massimo 2 parti) per ottenere packageName e message
// 3. Crea una funzione logInit(packageName, message string) che aggiunga
// "[INIT] [packageName]: message" alla slice globale initLog
// 4. Mostra l'intestazione della sequenza di inizializzazione e tutte le voci del log di inizializzazione
// 5. Mostra l'intestazione dell'esecuzione principale ed elabora ogni operazione di mainOps
// - Stampa "Executing: <op>" per ogni operazione
// - Aggiungi "[MAIN] Operation: <op>" a initLog
// 6. Mostra il riepilogo dell'esecuzione (numero di pacchetti, numero di operazioni, numero totale di voci del log)
// 7. Mostra il log completo e il messaggio finale di completamento
}Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Logica e flusso
1Flusso di controllo avanzato
Switch con `fallthrough`Uscire dai cicli annidatiContinuare un ciclo specificoL'istruzione `goto`Riepilogo - Controllo avanzato dei cicli4Progetto: semplice lista di attività
Configurazione del progettoAggiungere un’attività2Struct e metodi
Definire metodi sugli structReceiver per valoreReceiver con puntatoreScegliere i receiverMetodi vs funzioniRiepilogo - comportamento degli struct5Mappe in dettaglio
Mappe di structPuntatori come valori delle mappeVerificare le mappe nilConfrontare le mappeRiepilogo - Contatore della frequenza delle parole3Interfacce (le basi)
Che cos’è un’interfaccia?Definire un’interfacciaImplementare un’interfacciaUsare i tipi interfacciaInterfaccia vuotaAsserzioni di tipoSwitch di tipoRiepilogo: forme e comportamentiEsercitati da solo: Compilatore Go online