Heim  >  Artikel  >  Backend-Entwicklung  >  Wie funktioniert der Golang-Paketimportvorgang? Gibt es eine Möglichkeit, ein Paket mehrmals im selben Modul zu initialisieren?

Wie funktioniert der Golang-Paketimportvorgang? Gibt es eine Möglichkeit, ein Paket mehrmals im selben Modul zu initialisieren?

PHPz
PHPznach vorne
2024-02-06 08:54:08941Durchsuche

golang 包导入流程如何工作?是否有一种方法可以在同一模块中多次初始化一个包?

Frageninhalt

Ich bin neu bei Golang und beschäftige mich derzeit mit Paketen und deren Funktionsweise. Ich habe ein paar Fragen zu diesem Import. Ich lese diesen Beitrag (er hat über 7.000 „Gefällt mir“-Angaben, also denke ich, dass er korrekt ist + es ist das Erste, was Google mir anzeigt, wenn ich tippe golang 包 ).

Um zu erklären, was ich nicht verstehe, möchte ich zunächst darüber schreiben, wie die Projektstruktur aussieht und was der Inhalt aller Dateien ist.

pkg
├── mypkg
|  └── mypkg.go
|
├── pkg1
|  └── pkg1.go
|
└── pkg2
   └── pkg2.go
go.mod
main.go

Wie Sie sehen, habe ich Module mit 3 Paketen (4 Pakete inklusive Hauptpaket). Der Inhalt aller Pakete ist unten aufgeführt.

Inhalt von

pkg1.go:

package pkg1

import (
    "fmt"
    "mymod/pkg/mypkg"
)

func init() {
    fmt.println("hello everyone from pkg1 init")
}

func hellofrompkg1() {
    fmt.println("hello from pk1")
    mypkg.print()
}
Inhalt von

pkg2.go:

package pkg2

import (
    "fmt"
    "mymod/pkg/mypkg"
)

func init() {
    fmt.println("hello everyone from pkg2 init")
}

func hellofrompkg2() {
    fmt.println("hello from pk2")
    mypkg.print()
}
Inhalt von

mypkg:

package mypkg

import "fmt"

func init() {
    fmt.println("hello everyone from mypkg init")
}

var prom = 10

func print() {
    fmt.printf("address of prom inside mypkg is: %p\n", &prom)
}

main.go-Inhalt:

package main

import (
    "fmt"
    "mymod/pkg/pkg1"
    "mymod/pkg/pkg2"
)

func init() {
    fmt.println("hello everyone from main init")
}

func main() {
    pkg1.hellofrompkg1()
    pkg2.hellofrompkg2()
}

Daher main.go 包含 pkg1pkg2,并且 pkg1pkg2 都包含 mypkg. In dem von mir zitierten Artikel heißt es (in Fettdruck):

the main thing to remember is, an imported package is initialized only once per package.

Vor diesem Hintergrund würde ich erwarten, dass die Ausgabe meines Programms etwa so aussieht:

hello everyone from mypkg init
hello everyone from pkg1 init
hello everyone from mypkg init
hello everyone from pkg2 init
hello everyone from main init
hello from pk1
address of prom inside mypkg is: 0xfee360 (some address)
hello from pk2
address of prom inside mypkg is: 0xf321a3 (another address)

Meine Erwartung ist es, diese Schritte zu befolgen:

  • Geben Sie das Hauptpaket (1) ein
  • pkg1-Paket initialisiert (2)
    • mypkg-Paket wurde initialisiert (2.1)
      • Alle globalen Variablen in mypkg werden initialisiert -prom In meinem Fall (2.1.1)
      • Rufen Sie die Init-Funktion von mypkg (2.1.2) auf
    • Rufen Sie die Init-Funktion von pkg1 (2.2) auf
  • pkg2-Paket initialisiert (3)
    • mypkg-Paket wurde initialisiert (3.1)
      • Alle globalen Variablen in mypkg werden initialisiert -prom In meinem Fall (3.1.1)
      • Rufen Sie die Init-Funktion von mypkg (3.1.2) auf
    • Rufen Sie die Init-Funktion von pkg2 (3.2) auf
  • Initialisierung des Hauptpakets (4)
  • Rufen Sie die Init-Funktion (5) von main auf
  • Die Hauptfunktion des Hauptpakets heißt (6)

Stattdessen erhalte ich die folgende Ausgabe:

Hello everyone from mypkg init
Hello everyone from pkg1 init
Hello everyone from pkg2 init
Hello everyone from main init
Hello from pk1
address of prom inside mypkg is: 0x8fe360
Hello from pk2
address of prom inside mypkg is: 0x8fe360

Es sieht so aus, als ob mypkg während des ersten Imports nur einmal initialisiert wird ? ! Außerdem hat die globale Variable prom 在 pkg1 和 pkg2 中的地址是相同的(在本例中为 0x8fe360 in pkg1 und pkg2 die gleiche Adresse (in diesem Fall 0x8fe360).

Meine Frage lautet also:

  1. Hat der Autor des Artikels einen Fehler gemacht? Importierte Pakete werden nicht nur einmal pro Paket initialisiert, sondern einmal pro Modul? Bedeutet das, dass globale Variablen in einem Paket im gesamten Modul immer gleich (gleiche Adresse) sind, unabhängig davon, wie oft das Paket eingebunden wird und von wo? Ich meine, sie werden beim ersten Import nur
  2. einmal
  3. initialisiert? Gibt es eine Möglichkeit, meinen „Flow“ zum Funktionieren zu bringen? Ich meine, jeder Import initialisiert ein Paket unabhängig? In meinem Beispiel bedeutet dies, noch einmal in
  4. zu initialisieren.
  5. mypkgpkg1 中初始化一次,在 pkg2Wenn das, was ich gelesen habe, falsch ist, hat jemand einen guten Artikel über Pakete und Module in Go?
  6. Ich weiß, dass es bei diesen Fragen für einige Leute um grundlegende Kenntnisse von Golang geht, aber bei mir als Anfänger hat es zu einigen Missverständnissen geführt. Darüber hinaus stimmten die Ergebnisse der Programmarbeit nicht mit denen überein, die die Autoren der Artikel geschrieben hatten, die bei der Google-Suche zuerst auftauchten. Jede Hilfe ist willkommen. wünsche dir das Beste!

Richtige Antwort

Die im Programm enthaltenen Pakete sind eine Menge, die den transitiven Abschluss aller importierten Pakete ab
darstellt. Das heißt:

main

Dies ist ein Set. Jedes importierte Paket ist nur einmal enthalten. Das heißt, wenn Sie eine Variable in einem Paket definieren, erscheint diese nur einmal.
  • Alle importierten Pakete und die Pakete, die sie rekursiv importieren, sind in der endgültigen Binärdatei enthalten.
  • Was die Initialisierung betrifft: Ihre Schritte sind korrekt, nur mehrere Kopien von
.

Das obige ist der detaillierte Inhalt vonWie funktioniert der Golang-Paketimportvorgang? Gibt es eine Möglichkeit, ein Paket mehrmals im selben Modul zu initialisieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen