J'ai essayé de trouver une explication précise de ce que fait la init()
fonction dans Go. J'ai lu ce qu'Efficace Go dit, mais je ne savais pas si j'avais bien compris ce qu'il disait. La phrase exacte dont je ne suis pas sûr est la suivante:
Et enfin signifie finalement: init est appelé après que toutes les déclarations de variables du package ont évalué leurs initialiseurs, et celles-ci ne sont évaluées qu'après que tous les packages importés ont été initialisés.
Que veut all the variable declarations in the package have evaluated their initializers
dire? Cela signifie-t-il que si vous déclarez des variables "globales" dans un package et ses fichiers, init () ne s'exécutera pas tant que tout n'aura pas été évalué, puis exécutera toutes les fonctions init puis main () lorsque ./main_file_name sera exécuté?
J'ai également lu le livre de go de Mark Summerfield:
Si un package possède une ou plusieurs fonctions init (), elles sont automatiquement exécutées avant l'appel de la fonction main () du package principal.
À ma connaissance, init()
n'est pertinent que lorsque vous exécutez l'intention d'exécuter main () non? ou le package principal. N'importe qui comprend plus précisément init()
n'hésitez pas à me corriger
init()
est une chose par paquet, je pense ... Ainsi, cela signifie-t-il que si différents fichiers ont le leurinits
, toutes les inints sont toujours exécutées juste avant l'exécution de main ()? Pouvez-vous également clarifier pour moi une chose, pourquoi auriez-vous un init () sans main et comment cela fonctionne-t-il? Cela signifie-t-il que init () est la dernière chose exécutée avant l'importation du package? Sinon, s'il n'est pas importé et qu'il n'y a pas de main, le programme ne s'exécutera jamais ... non? (sauf si c'est un fichier de test je suppose ...)main
, par exemple si vous devez initialiser plusieurs variables ou charger des fichiers ou faire des calculs ponctuels. maintenant, si votre programme entier est un package qui n'est pas vraiment nécessaire, cependant s'il s'agit de plusieurs packages, certains d'entre eux pourraient avoir besoin d'une initialisation spécifique.init
est avec une architecture enfichable, comme avec Cobra Commander . Remarquez commentinit
est référencé dans les exemplesVoir cette photo. :)
import --> const --> var --> init()
Si un package importe d'autres packages, les packages importés sont initialisés en premier.
La constante du paquet courant est alors initialisée.
Les variables du paquet courant sont alors initialisées.
Enfin, la
init()
fonction du paquet courant est appelée.la source
Quelque chose à ajouter à cela (que j'aurais ajouté comme commentaire mais au moment de la rédaction de cet article, je n'avais pas encore assez de réputation)
Ayant plusieurs inits dans le même package, je n'ai pas encore trouvé de moyen garanti de savoir dans quel ordre ils seront exécutés. Par exemple, j'ai:
Les deux
config.go
etrouter.go
contiennent desinit()
fonctions, mais lors de l' exécutionrouter.go
de la fonction de » couru d' abord (qui a causé mon application à la panique).Si vous êtes dans une situation où vous avez plusieurs fichiers, chacun avec sa propre
init()
fonction, sachez que vous n'êtes pas assuré d'en obtenir un avant l'autre. Il est préférable d'utiliser une affectation de variable comme OneToOne le montre dans son exemple. La meilleure partie est: Cette déclaration de variable se produira avant TOUTES lesinit()
fonctions du package.Par exemple
config.go:
router.go:
indépendamment du fait qu'il
var ConfigSuccess = configureApplication()
existe dansrouter.go
ouconfig.go
, il sera exécuté avant que SOITinit()
soit exécuté.la source
func initialize|loadConfig|connect
séparé defunc init
, laissant func init () pour les trucs de base (sans panique). Cette séparation supprime également la nécessité du hack pour garantir l'ordre d'initialisation. J'espère être utile.init()
appels dans un seul package est dicté par la façon dont ils sont introduits dans le compilateur; l'go
outil classe les fichiers par ordre alphabétique. Dès lors, dans un même fichier, ils sont initialisés dans l'ordre syntaxique. modifié pour le choix des motsVoici un autre exemple - https://github.com/alok87/gobyexample/blob/master/init/init.go
Sortie du programme ci-dessus
la source
Prenons par exemple un framework ou une bibliothèque que vous concevez pour d'autres utilisateurs, ces utilisateurs auront éventuellement un
main function
dans leur code afin d'exécuter leur application. Si l'utilisateur importe directement un sous-package du projet de votre bibliothèque, alors leinit
sous-package sera appelé ( une fois ) tout d'abord. De même pour le paquet racine de la bibliothèque, etc ...Il y a de nombreuses fois où vous pouvez souhaiter qu'un bloc de code soit exécuté sans l'existence d'un
main func
, directement ou non.Si vous, en tant que développeur de la bibliothèque imaginaire, importez le sous-package de votre bibliothèque qui a une
init
fonction, il sera appelé en premier et une fois , vous n'en avez pasmain func
mais vous devez vous assurer que certaines variables, ou une table, sera initialisé avant les appels des autres fonctions.Une bonne chose à retenir et de ne pas craindre, est que: l'
init
execute toujours une fois par application.init
l'exécution se produit:init
fonction du package "appelant",main func
,var = [...] or cost = [...]
,Lorsque vous importez un package, il exécute toutes ses fonctions init, par ordre .
Je vais donner un très bon exemple de fonction init. Il ajoutera des types MIME à une bibliothèque go standard nommée
mime
et une fonction aumime
niveau du package utilisera directement le package standard pour obtenir les types MIME personnalisés qui sont déjà initialisés à sainit
fonction:J'espère que cela vous a aidé, vous et d'autres utilisateurs, n'hésitez pas à poster à nouveau si vous avez plus de questions!
la source
https://golang.org/ref/mem#tmp_4
la source
init
sera appelé partout utilise son package (peu importe l'importation ou l'importation vide), mais une seule fois.c'est un package:
n'importe quel paquet (paquet principal ou tout paquet de test) l'importez comme vide:
ou importez-le en utilisant func:
l'init ne se connectera
0
qu'une seule fois. le premier paquet l'utilisant, sa fonction init s'exécutera avant l'init du paquet. Donc:A appelle B, B appelle C, tous ont une fonction init, les init de C seront exécutés en premier avant les B, les B avant les A.
la source
fonction d'initialisation mutil dans un seul paquet exécuter l'ordre:
la fonction init () du fichier const et variable est exécutée
fonction init exécute l'ordre par le nom de fichier asc
la source
L'init func s'exécute d'abord, puis main. Il est utilisé pour définir quelque chose avant l'exécution de votre programme, par exemple:
Accéder à un modèle, exécuter le programme en utilisant tous les cœurs, vérifier les Goos et l'arc, etc.
la source