Die `init`-Funktion
Teil des Abschnitts Logik & Ablauf der GO-Journey von Coddy — Lektion 56 von 68.
Die init-Funktion ist eine spezielle Funktion in Go, die automatisch ausgeführt wird, wenn ein Package importiert wird. Im Gegensatz zu regulären Funktionen rufen Sie init nicht direkt auf – Go führt sie während des Package-Initialisierungsprozesses für Sie aus.
So definieren Sie eine init-Funktion:
package mypackage
import "fmt"
func init() {
fmt.Println("Package mypackage is being initialized!")
}Die init-Funktion weist einige einzigartige Merkmale auf: Sie nimmt keine Parameter entgegen, gibt keine Werte zurück und wird ausgeführt, bevor die main-Funktion startet. Dies macht sie ideal für das Einrichten des Anfangszustands, das Registrieren von Komponenten oder das Ausführen von einmaligen Setup-Aufgaben, die Ihr Paket benötigt.
Wenn Sie ein Paket importieren, das eine init-Funktion enthält, werden Sie deren Auswirkungen sofort bemerken, selbst wenn Sie keine der exportierten Funktionen des Pakets verwenden. Aus diesem Grund ist das Importmuster mit dem Blank-Identifier, das Sie zuvor gelernt haben, so nützlich – es ermöglicht Ihnen, die Initialisierung eines Pakets auszulösen, ohne dessen Code direkt zu verwenden.
Aufgabe
EinfachErstellen Sie ein Paket-Initialisierungssystem, das demonstriert, wie init-Funktionen automatisch ausgeführt werden, wenn Pakete importiert werden. Sie werden ein Protokollierungssystem erstellen, in dem sich verschiedene Pakete selbst initialisieren und ihre Startsequenz verfolgen.
Sie erhalten zwei Eingaben:
- Einen String, der Paketdefinitionen im Format
"package1:message1,package2:message2,package3:message3"enthält (z. B."database:Database connection pool initialized,cache:Cache system ready,logger:Logging system started") - Einen String, der die Operationen des Hauptprogramms im Format
"operation1,operation2,operation3"enthält (z. B."start_server,process_requests,shutdown")
Ihre Aufgabe ist es:
- Die erste Eingabe durch Trennen an Kommas zu parsen, um einzelne Paketdefinitionen zu erhalten
- Für jede Paketdefinition an Doppelpunkten zu trennen, um den Paketnamen und die Initialisierungsnachricht zu erhalten
- Ein globales Slice namens
initLogzu erstellen, um Initialisierungsnachrichten zu verfolgen - Eine Funktion namens
logInitzu erstellen, die einen Paketnamen und eine Nachricht entgegennimmt und dann die formatierte Nachricht"[INIT] [package_name]: [message]"zuminitLog-Slice hinzufügt - Die Paket-Initialisierung zu simulieren, indem
logInitfür jedes Paket in der Reihenfolge aufgerufen wird, in der sie in der Eingabe erscheinen - Den Header für die Initialisierungssequenz anzuzeigen:
"=== PACKAGE INITIALIZATION SEQUENCE ===" - Jede Initialisierungsnachricht aus dem
initLog-Slice auszugeben - Den Header für das Hauptprogramm anzuzeigen:
"=== MAIN PROGRAM EXECUTION ===" - Folgendes auszugeben:
"All packages initialized successfully" - Die zweite Eingabe durch Trennen an Kommas zu parsen, um einzelne Operationen zu erhalten
- Für jede Operation im Hauptprogramm:
- Folgendes auszugeben:
"Executing: [operation]" - Eine Nachricht zum Log hinzuzufügen:
"[MAIN] Operation: [operation]" - Die Zusammenfassung der Ausführung anzuzeigen:
"=== EXECUTION SUMMARY ===""Packages initialized: [number_of_packages]""Main operations executed: [number_of_operations]""Total log entries: [total_number_of_log_entries]"- Das vollständige Log anzuzeigen:
"=== COMPLETE EXECUTION LOG ==="- Jeden Eintrag aus dem vollständigen Log auszugeben (sowohl Initialisierungsnachrichten als auch Hauptoperationen)
- Die Abschlussmeldung anzuzeigen:
"Program execution completed - all init functions ran before main"
Verwenden Sie das strings-Paket, um die Eingabestrings zu trennen, und das fmt-Paket für die formatierte Ausgabe. Diese Herausforderung demonstriert, wie init-Funktionen automatisch während des Paketimports ausgeführt werden und immer vor der main-Funktion laufen, was sie ideal für Paket-Setup- und Initialisierungsaufgaben macht.
Probier es selbst
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
// Globaler Slice zur Verfolgung von Initialisierungsnachrichten
var initLog []string
func main() {
reader := bufio.NewReader(os.Stdin)
// Eingabe lesen (bufio verarbeitet Zeilen mit Leerzeichen korrekt)
packageDefs, _ := reader.ReadString('\n')
packageDefs = strings.TrimRight(packageDefs, "\r\n")
mainOps, _ := reader.ReadString('\n')
mainOps = strings.TrimRight(mainOps, "\r\n")
// TODO: Schreiben Sie Ihren Code unten
// 1. Parsen Sie packageDefs durch Aufteilen bei "," um einzelne Paket-Einträge zu erhalten
// 2. Teilen Sie jeden Eintrag bei ":" (max. 2 Teile) auf, um packageName und message zu erhalten
// 3. Erstellen Sie eine logInit(packageName, message string) Funktion, die
// "[INIT] [packageName]: message" an den globalen initLog-Slice anhängt
// 4. Zeigen Sie den Header der Initialisierungssequenz und alle Initialisierungs-Logeinträge an
// 5. Zeigen Sie den Header der Hauptausführung an und verarbeiten Sie jede Operation aus mainOps
// - Geben Sie "Executing: <op>" für jede Operation aus
// - Hängen Sie "[MAIN] Operation: <op>" an initLog an
// 6. Zeigen Sie die Zusammenfassung der Ausführung an (Paketanzahl, Operationsanzahl, Gesamtanzahl der Logeinträge)
// 7. Zeigen Sie das vollständige Log und die abschließende Abschlussmeldung an
}Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Logik & Ablauf
1Fortgeschrittener Kontrollfluss
Switch mit `fallthrough`Abbrechen von verschachtelten SchleifenFortsetzen einer bestimmten SchleifeDie `goto`-AnweisungZusammenfassung – Fortgeschrittene Schleifensteuerung4Projekt: Einfache Aufgabenliste
Projekt-SetupEine Aufgabe hinzufügen2Structs und Methoden
Methoden für Structs definierenValue ReceiverPointer ReceiverReceiver auswählenMethoden vs. FunktionenZusammenfassung – Struct-Verhalten5Maps im Detail
Maps von StructsPointer als Map-WertePrüfen auf Nil-MapsMaps vergleichenZusammenfassung – Wortfrequenz-Zähler8Projekt: Einfache Bestandsverwaltung
ProjektübersichtLagerbestand prüfen11Abschlussherausforderungen
Einfache KontaktlisteEinfacher Zahlen-ValidatorSammler für eindeutige Elemente3Interfaces (Die Grundlagen)
Was ist ein Interface?Ein Interface definierenEin Interface implementierenInterface-Typen verwendenLeeres InterfaceType AssertionsType SwitchZusammenfassung – Formen und Verhalten