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

PHPz
Freigeben: 2024-02-06 08:54:08
nach vorne
940 Leute haben es durchsucht

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
Nach dem Login kopieren

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()
}
Nach dem Login kopieren
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()
}
Nach dem Login kopieren
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)
}
Nach dem Login kopieren

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()
}
Nach dem Login kopieren

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.
Nach dem Login kopieren

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)
Nach dem Login kopieren

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
Nach dem Login kopieren

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!

Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!