Wann wird init() in Go ausgeführt? Analyse anhand von Beispielen

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Wann wird init() in Go ausgeführt? Analyse anhand eines realen Beispiels



Stellen Sie sich vor: Sie schreiben einen Mikroservice in Go. In einem der Pakete haben Sie init() deklariert, um die Konfiguration zu laden. Sie starten die Anwendung – und plötzlich stürzt sie mit nil pointer dereference ab. Sie geraten in Panik: "Warum? Die Konfiguration hätte doch zuerst geladen werden müssen!"



Kommt Ihnen das bekannt vor? Wenn ja, sind Sie nicht allein. Die Frage "When does the init() function run?" ist eine der beliebtesten auf Stack Overflow (tausende Aufrufe). Lassen Sie uns ein für alle Mal klären, wann und in welcher Reihenfolge init() in Go ausgeführt wird, damit Sie nicht mehr in diese Falle tappen.



Was ist init() und wozu dient es?



In Go ist init() eine spezielle Funktion ohne Parameter und Rückgabewert. Sie wird nicht explizit aufgerufen. Die Go-Laufzeitumgebung führt sie automatisch vor der Ausführung der Funktion main() aus.



Wozu wird das benötigt?



  • Initialisierung globaler Variablen, die eine komplexe Logik erfordern (z. B. Lesen aus einer Datei).
  • Registrierung von Datenbanktreibern oder HTTP-Handlern.
  • Überprüfung der Umgebung (Umgebungsvariablen, Verfügbarkeit von Ressourcen).


Aber die Hauptregel lautet: Sie sollten sich niemals auf die Ausführungsreihenfolge von init() zwischen verschiedenen Dateien desselben Pakets verlassen. Und hier ist der Grund dafür.



Wann genau wird init() ausgeführt? Die genaue Reihenfolge



Go führt init() nach strengen Regeln aus. Lassen Sie uns diese im Detail betrachten.



Regel Nr. 1: Ein Paket – eine Reihenfolge

Innerhalb eines Pakets wird init() in der Reihenfolge der Dateideklarationen ausgeführt (alphabetisch nach Dateinamen). Dies ist jedoch ein Implementierungsdetail – darauf sollte man sich besser nicht verlassen.



Regel Nr. 2: Zuerst Variableninitialisierung, dann init()

Vor dem Aufruf von init() initialisiert Go alle globalen Variablen im Paket. Wenn eine Variable von einer anderen Variable im selben Paket abhängt, ist die Reihenfolge ihrer Deklaration entscheidend.



package config

var AppName string = "MyApp"var Version string = getVersion() // wird vor init() aufgerufen

func init() { // Hier sind AppName und Version bereits verfügbar println("Init gestartet für", AppName)}

func getVersion() string { return "1.0.0"}


Regel Nr. 3: Importierte Pakete werden zuerst initialisiert

Dies ist die wichtigste Regel. Wenn Paket A Paket B importiert, werden zuerst alle init() in Paket B ausgeführt und erst dann die in A. Go erstellt einen Abhängigkeitsgraphen und führt die Initialisierung "von unten nach oben" durch.



// Paket databasepackage database

func init() { println("1. database init")}

// Paket main (importiert database)package main

import "myapp/database"

func init() { println("2. main init")}

func main() { println("3. main function")}

// Ausgabe:// 1. database init// 2. main init// 3. main function


Regel Nr. 4: Mehrere init() in einer Datei – möglich, aber nicht nötig

In einer Datei können mehrere init() vorhanden sein. Sie werden in der Reihenfolge ihrer Deklaration ausgeführt. Dies erschwert jedoch die Lesbarkeit des Codes. Es ist besser, die Logik in einer Funktion zu bündeln.



Lebendiges Beispiel: Was passiert, wenn man die Reihenfolge falsch einschätzt?



Lassen Sie uns einen typischen Anfängerfehler simulieren. Angenommen, wir haben ein Paket config, das Einstellungen aus einer Datei liest, und ein Paket app, das diese Einstellungen verwendet.



// config.gopackage config

var Settings map[string]string

func init() { // Simuliert das Lesen einer Datei Settings = map[string]string{ "port": "8080", "host": "localhost", } println("Konfiguration geladen")}

// app.gopackage app

import "myapp/config"

var ServerPort string

func init() { // FEHLER: wenn config.Settings noch nicht initialisiert ist

Blogs

Buchempfehlungen