ProgrammationDéveloppeur Backend

Comment fonctionne la fonction init en Go ? Comment l'initialisation se déroule-t-elle dans les paquets et comment gérer correctement les dépendances et l'ordre d'initialisation ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Go prend en charge la fonction init pour exécuter du code d'initialisation avant le début de main(). Lors du lancement d'un programme Go, le compilateur appelle automatiquement toutes les fonctions init déclarées dans chaque paquet, après l'initialisation des variables de paquet.

Historique de la question : nécessité de préparer une fois l'état du paquet avant son utilisation.

Problème : l'ordre d'initialisation de init devient souvent une source d'erreurs implicites : il est difficile de contrôler quand une fonction init particulière sera exécutée, surtout en cas de nombreuses dépendances entre les paquets.

Solution :

  • Dans chaque paquet, n'importe quelle fonction avec la signature func init() est autorisée. Les appels se font dans l'ordre déterminé par les dépendances des importations. Il est déconseillé d'abuser des fonctions init — il est recommandé de les garder avec un code minimal.

Exemple de code :

package example import "fmt" var Cfg string = "default" func init() { fmt.Println("example init") Cfg = "configured" }

Caractéristiques clés :

  • Toutes les fonctions init d'un paquet sont appelées après l'initialisation des variables globales/de paquet.
  • Si plusieurs fonctions init, l'ordre de leur appel est le même que celui de leur déclaration dans le fichier.
  • L'ordre d'initialisation des paquets est déterminé par l'arbre des importations — d'abord les dépendances, ensuite le paquet lui-même.

Questions piégeuses.

Peut-on définir plus d'une fonction init dans un même fichier ?

Oui, plusieurs fonctions init sont autorisées — elles seront appelées dans l'ordre de leur déclaration.

Que se passe-t-il si le paquet est importé uniquement de manière indirecte (via _ "package") ?

Seules les fonctions init et l'initialisation des variables de ce paquet seront exécutées.

Les fonctions init peuvent-elles renvoyer une valeur ou une erreur ?

Non. La signature de init est immuable : func init(), sans paramètres ni valeurs de retour.

Erreurs typiques et anti-modèles

  • Utilisation de init pour une logique métier complexe ou une initialisation lourde.
  • Modification cachée des variables via init dans différents paquets, entraînant un comportement imprévisible.
  • Multiples fonctions init sans nécessité.

Exemple de la vie réelle

Cas négatif

Un grand projet s'appuyait sur des fonctions init complexes, initialisant des états globaux avec des dépendances entre paquets. Cela causait des erreurs aléatoires au démarrage.

Avantages :

  • Initialisation simplifiée (pas d'appel explicite dans main).

Inconvénients :

  • La dépendance à l'ordre et l'accès compliquait les tests et le débogage.

Cas positif

Init est utilisé uniquement pour des tâches basiques ou spécifiques aux tests, le reste est déplacé dans des fonctions explicites appelées depuis main(). L'ordre d'exécution est clair, facilité des tests.

Avantages :

  • Transparence de l'exécution et gestion des dépendances.

Inconvénients :

  • Nécessité d'appeler explicitement la fonction d'initialisation, un peu plus de code.