So organisieren Sie ein Go-Projekt mit mehreren Dateien: unter der Haube

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Ein Go-Projekt aus einer Datei ist einfach. Aber aus zehn?

\n\n

Stellen Sie sich vor: Sie schreiben in Go ein Dienstprogramm zum Parsen von Logs. Zunächst passt alles in eine Datei main.go. Es funktioniert, alles bestens. Aber nach einer Woche wächst der Code: Es kommen Funktionen zum Lesen von Dateien, zum Filtern, zum Senden von Daten an die Datenbank hinzu. Eine Datei verwandelt sich in ein Monster mit 2000 Zeilen. Kommt Ihnen das bekannt vor?

\n\n

Hier stellt sich die Frage, die jeden zweiten Anfänger quält (und die tausende Aufrufe auf Stack Overflow gesammelt hat): Wie organisiert man ein Go-Projekt mit mehreren Dateien richtig? Nicht einfach den Code auf Ordner verteilen, sondern so, dass es funktioniert, kompiliert und keine Fehler wie undefined oder import cycle not allowed verursacht.

\n\n

In diesem Artikel geben wir nicht nur eine Vorlage. Wir schauen unter die Haube des Go-Compilers und verstehen, wie die Verknüpfung von Dateien, Paketen und Modulen tatsächlich funktioniert. Sie erfahren, warum go run *.go manchmal hilft und manchmal nicht, und wie Sie eine Architektur aufbauen, die skalierbar ist.

\n\n

Datei, Paket, Modul – die grundlegende Hierarchie

\n\n

Bevor wir uns in den Code stürzen, lassen Sie uns drei Schlüsselbegriffe klären. Ohne sie wird die Organisation eines Go-Projekts zum Ratespiel.

\n\n
    \n
  • Datei (.go) – ist einfach eine Textdatei mit Code. Für sich allein genommen bedeutet sie dem Compiler nichts.
  • \n
  • Paket (package) – ist eine logische Gruppe von Dateien, die sich im selben Verzeichnis befinden. Alle Dateien in einem Ordner müssen dieselbe package-Deklaration haben. Wenn sich in einem Ordner Dateien mit unterschiedlichen Paketen befinden, gibt der Compiler einen Fehler aus.
  • \n
  • Modul (go.mod) – ist die Wurzel Ihres Projekts. Es definiert den Modulnamen, seine Abhängigkeiten und die Go-Version. Ein Modul kann viele Pakete enthalten.
  • \n
\n\n

Goldene Regel: Ein Verzeichnis = ein Paket. Ausnahme sind Tests, aber dazu später mehr.

\n\n

Praktisches Beispiel: Projekt "Log-Analysator"

\n\n

Lassen Sie uns ein kleines Projekt erstellen, das eine Logdatei liest, Zeilen nach einem Schlüsselwort filtert und das Ergebnis ausgibt. Wir machen das zuerst "auf die harte Tour" (eine Datei) und teilen es dann richtig in mehrere Dateien auf.

\n\n

Phase 1: Alles in einer Datei (schlecht)

\n\n
// main.go\npackage main\n\nimport (\n    "bufio"\n    "fmt"\n    "os"\n    "strings"\n)\n\nfunc readLog(path string) ([]string, error) {\n    file, err := os.Open(path)\n    if err != nil {\n        return nil, err\n    }\n    defer file.Close()\n\n    var lines []string\n    scanner := bufio.NewScanner(file)\n    for scanner.Scan() {\n        lines = append(lines, scanner.Text())\n    }\n    return lines, scanner.Err()\n}\n\nfunc filterLines(lines []string, keyword string) []string {\n    var result []string\n    for _, line := range lines {\n        if strings.Contains(line, keyword) {\n            result = append(result, line)\n        }\n    }\n    return result\n}\n\nfunc main() {\n    lines, err := readLog("server.log")\n    if err != nil {\n        fmt.Println("Fehler:", err)\n        return\n    }\n    filtered := filterLines(lines, "ERROR")\n    for _, l := range filtered {\n        fmt.Println(l)\n    }\n}\n
\n\n

Es funktioniert. Aber stellen Sie sich vor, dass readLog komplexer wird (Unterstützung für gzip, Kodierungen) und filterLines mit regulären Ausdrücken überladen wird. Die Datei wird unlesbar.

\n\n

Phase 2: Aufteilen in Pakete (richtig)

\n\n

Erstellen wir eine Verzeichnisstruktur:

\n\n
log-analyzer/\n├── go.mod\n├── main.go\n└── pkg/\n    └── logreader/\n        ├── reader.go\n        └── filter.go\n
\n\n

Initialisieren wir das Modul:

\n\n
go mod init log-analyzer
\n\n

Jetzt schreiben wir den Code für das Paket logreader. Beachten Sie: Alle Dateien im Ordner pkg/logreader/ haben package logreader.

\n\n

pkg/logreader/reader.go

\n\n
package logread                

Blogs

Buchempfehlungen