Quand init() s'exécute-t-il en Go ? Analyse avec des exemples

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Quand init() s'exécute-t-il en Go ? Analyse avec un exemple concret



Imaginez : vous écrivez un microservice en Go. Dans l'un des packages, vous avez déclaré init() pour charger la configuration. Vous lancez l'application — et soudain, elle plante avec une nil pointer dereference. Vous paniquez : "Pourquoi ? La configuration aurait dû être chargée en premier !"



Cela vous semble familier ? Si oui, vous n'êtes pas seul. La question "When does the init() function run?" est l'une des plus populaires sur Stack Overflow (des milliers de vues). Comprenons une fois pour toutes quand et dans quel ordre init() s'exécute en Go, afin que vous ne tombiez plus dans ce piège.



Qu'est-ce que init() et à quoi sert-il ?



En Go, init() est une fonction spéciale sans paramètres ni valeur de retour. Elle n'est pas appelée explicitement. C'est le runtime Go qui l'exécute automatiquement avant l'exécution de la fonction main().



À quoi cela sert-il ?



  • Initialiser des variables globales qui nécessitent une logique complexe (par exemple, la lecture d'un fichier).
  • Enregistrer des pilotes de base de données ou des gestionnaires HTTP.
  • Vérifier l'environnement (variables d'environnement, disponibilité des ressources).


Mais la règle principale est la suivante : vous ne devez jamais vous fier à l'ordre d'exécution de init() entre différents fichiers d'un même package. Et voici pourquoi.



Quand exactement init() s'exécute-t-il ? L'ordre précis



Go exécute init() selon des règles strictes. Détaillons-les point par point.



Règle n°1 : Un package — un ordre

Au sein d'un même package, init() s'exécute dans l'ordre de déclaration des fichiers (par ordre alphabétique des noms de fichiers). Mais c'est un détail d'implémentation — il vaut mieux ne pas s'y fier.



Règle n°2 : D'abord l'initialisation des variables, ensuite init()

Avant d'appeler init(), Go initialise toutes les variables globales du package. Si une variable dépend d'une autre variable du même package, l'ordre de leur déclaration est important.



package config

var AppName string = "MyApp"var Version string = getVersion() // sera appelée avant init()

func init() { // AppName et Version sont déjà disponibles ici println("Init started for", AppName)}

func getVersion() string { return "1.0.0"}


Règle n°3 : Les packages importés sont initialisés en premier

C'est la règle la plus importante. Si le package A importe le package B, alors tous les init() du package B s'exécuteront en premier, et ensuite seulement ceux du package A. Go construit un graphe de dépendances et effectue l'initialisation "de bas en haut".



// Package databasepackage database

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

// Package main (importe database)package main

import "myapp/database"

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

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

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


Règle n°4 : Plusieurs init() dans un même fichier — possible, mais déconseillé

Un même fichier peut contenir plusieurs init(). Ils s'exécuteront dans l'ordre de leur déclaration. Mais cela rend la lecture du code plus complexe. Il est préférable de regrouper la logique dans une seule fonction.



Exemple concret : que se passe-t-il si l'on se trompe dans l'ordre ?



Simulons une erreur typique de débutant. Supposons que nous ayons un package config qui lit les paramètres depuis un fichier, et un package app qui utilise ces paramètres.



// config.gopackage config

var Settings map[string]string

func init() { // Simulation de la lecture d'un fichier Settings = map[string]string{ "port": "8080", "host": "localhost", } println("Config loaded")}

// app.gopackage app

import "myapp/config"

var ServerPort string

func init() { // ERREUR : si config.Settings n'est pas encore initialisé

Blogs

Book Recommendations