Ich habe versucht, eine genaue Erklärung zu finden, was die init()
Funktion in Go tut. Ich habe gelesen, was Effective Go sagt, war mir aber nicht sicher, ob ich vollständig verstanden habe, was darin steht. Der genaue Satz, bei dem ich mir nicht sicher bin, lautet wie folgt:
Und schließlich heißt es endlich: init wird aufgerufen, nachdem alle Variablendeklarationen im Paket ihre Initialisierer ausgewertet haben, und diese werden erst ausgewertet, nachdem alle importierten Pakete initialisiert wurden.
Was heißt all the variable declarations in the package have evaluated their initializers
das Bedeutet dies, wenn Sie "globale" Variablen in einem Paket und seinen Dateien deklarieren, wird init () erst ausgeführt, wenn alles ausgewertet ist, und dann wird die gesamte init-Funktion und dann main () ausgeführt, wenn ./main_file_name ausgeführt wird?
Ich habe auch Mark Summerfields Go-Buch wie folgt gelesen:
Wenn ein Paket eine oder mehrere init () - Funktionen hat, werden diese automatisch ausgeführt, bevor die main () - Funktion des Hauptpakets aufgerufen wird.
init()
Ist nach meinem Verständnis nur relevant, wenn Sie beabsichtigen, main () auszuführen, oder? oder das Hauptpaket. Jeder, der es genauer versteht, kann init()
mich gerne korrigieren
init()
ist eine Sache pro Paket, denke ich ...inits
Bedeutet das also, dass, wenn verschiedene Dateien ihre eigenen haben , alle Intints immer direkt vor der Ausführung von main () ausgeführt werden? Können Sie mir auch eines klarstellen, warum Sie ein init () ohne main haben und wie funktioniert das? Bedeutet dies, dass init () das letzte ist, was ausgeführt wird, bevor das Paket importiert wird? Andernfalls wird das Programm niemals ausgeführt, wenn es nicht importiert wird und kein Hauptprogramm vorhanden ist ... richtig? (es sei denn, es ist eine Testdatei, denke ich ...)main
, beispielsweise wenn Sie mehrere Variablen initialisieren oder einige Dateien laden oder einmalige Berechnungen durchführen müssen. Wenn Ihr gesamtes Programm ein Paket ist, das nicht wirklich benötigt wird. Wenn es sich jedoch um mehrere Pakete handelt, müssen einige von ihnen möglicherweise eine spezifische Initialisierung durchführen.init
ist eine steckbare Architektur wie bei Cobra Commander . Beachten Sie, wieinit
in den Beispielen verwiesen wirdSiehe dieses Bild. :) :)
import --> const --> var --> init()
Wenn ein Paket andere Pakete importiert, werden die importierten Pakete zuerst initialisiert.
Die Konstante des aktuellen Pakets wird dann initialisiert.
Die Variablen des aktuellen Pakets werden dann initialisiert.
Schließlich wird die
init()
Funktion des aktuellen Pakets aufgerufen.quelle
Etwas hinzuzufügen (was ich als Kommentar hinzugefügt hätte, aber zum Zeitpunkt des Schreibens dieses Beitrags hatte ich noch nicht genug Ruf)
Da ich mehrere Inits im selben Paket habe, habe ich noch keinen garantierten Weg gefunden, um zu wissen, in welcher Reihenfolge sie ausgeführt werden. Zum Beispiel habe ich:
Beide
config.go
undrouter.go
enthalteninit()
Funktionen, aber beim Ausführen wurderouter.go
die Funktion zuerst ausgeführt (was meine App in Panik versetzte).Wenn Sie sich in einer Situation befinden, in der Sie mehrere Dateien haben, ist sich jede
init()
bewusst, dass Sie nicht garantiert eine vor der anderen erhalten. Es ist besser, eine Variablenzuweisung zu verwenden, wie OneToOne in seinem Beispiel zeigt. Das Beste daran ist: Diese Variablendeklaration erfolgt vor ALLENinit()
Funktionen im Paket.Zum Beispiel
config.go:
router.go:
Unabhängig davon, ob
var ConfigSuccess = configureApplication()
inrouter.go
oder vorhanden istconfig.go
, wird es ausgeführt, bevor EITHER ausgeführtinit()
wird.quelle
func initialize|loadConfig|connect
getrennterfunc init
, func init () für grundlegende Dinge (ohne Panik). Diese Trennung beseitigt auch die Notwendigkeit des Hacks, um die Init-Reihenfolge sicherzustellen. Ich hoffe, hilfreich zu sein.init()
Aufrufe innerhalb eines einzelnen Pakets hängt davon ab, wie sie in den Compiler eingespeist werden. Dasgo
Tool ordnet die Dateien alphabetisch. Von da an werden sie innerhalb einer einzelnen Datei in syntaktischer Reihenfolge initialisiert. bearbeitet für WortwahlHier ist ein weiteres Beispiel - https://github.com/alok87/gobyexample/blob/master/init/init.go
Ausgabe des obigen Programms
quelle
Nehmen Sie zum Beispiel ein Framework oder eine Bibliothek, die Sie für andere Benutzer entwerfen. Diese Benutzer haben schließlich eine
main function
in ihrem Code, um ihre App auszuführen. Wenn der Benutzer direkt ein Unterpaket des Projekts Ihrer Bibliothek importiertinit
, wird das dieses Unterpakets zunächst ( einmal ) aufgerufen . Gleiches gilt für das Root-Paket der Bibliothek usw.Es gibt viele Fälle, in denen Sie möchten, dass ein Codeblock
main func
direkt oder ohne das Vorhandensein von a ausgeführt wird.Wenn Sie als Entwickler der imaginären Bibliothek das Unterpaket Ihrer Bibliothek importieren, das eine
init
Funktion hat, wird es zuerst aufgerufen, und einmal haben Sie keine,main func
aber Sie müssen sicherstellen, dass einige Variablen oder eine Tabelle wird vor den Aufrufen anderer Funktionen initialisiert.Eine gute Sache zu erinnern und nicht zu befürchten ist , dass: die
init
immer ausführen einmal pro Anwendung.init
Ausführung geschieht:init
Funktion des "Anrufer" -Pakets,main func
,var = [...] or cost = [...]
,Wenn Sie ein Paket importieren, werden alle Init-Funktionen in der angegebenen Reihenfolge ausgeführt .
Ich werde ein sehr gutes Beispiel für eine Init-Funktion geben. Es werden Mime-Typen zu einer Standard-Go-Bibliothek mit dem Namen hinzugefügt,
mime
und eine Funktion auf Paketebene verwendet dasmime
Standardpaket direkt, um die benutzerdefinierten Mime-Typen abzurufen, die bereits bei ihrerinit
Funktion initialisiert wurden :Ich hoffe, das hat Ihnen und anderen Benutzern geholfen. Zögern Sie nicht, erneut zu posten, wenn Sie weitere Fragen haben!
quelle
https://golang.org/ref/mem#tmp_4
quelle
init
wird überall aufgerufen, verwendet sein Paket (egal Blankimport oder Import), aber nur einmal.Dies ist ein Paket:
Jedes Paket (Hauptpaket oder Testpaket) importiert es als leer:
oder importiere es mit func:
Der Init wird
0
nur einmal protokolliert . Beim ersten Paket, das es verwendet, wird seine Init-Funktion vor dem Init des Pakets ausgeführt. Damit:A ruft B an, B ruft C an, alle haben Init-Funktion, das Init des C wird zuerst vor dem B ausgeführt, das B vor dem A.
quelle
mutil init Funktion in einem Paket Ausführungsreihenfolge:
const und variable definierte Datei init () Funktion ausführen
init Funktion Ausführungsreihenfolge mit dem Dateinamen asc
quelle
Die Init-Funktion läuft zuerst und dann main. Es wird verwendet, um zuerst etwas festzulegen, bevor Ihr Programm ausgeführt wird, zum Beispiel:
Zugriff auf eine Vorlage, Ausführen des Programms mit allen Kernen, Überprüfen der Gänse und des Bogens usw.
quelle