Pakete in Go sind der grundlegende Baustein zur Organisation von Code und zur Verwaltung von Sichtbarkeiten. Historisch hat Go ein einfaches Modell für Importe und eine hierarchische Ordnerstruktur gewählt, um das Programmieren transparent zu machen und Unklarheiten bei der Auflösung von Abhängigkeiten, wie sie in C/C++ und Java vorkommen, zu vermeiden. Das Problem, das Go löst, ist die Schaffung einer verständlichen Projektstruktur, die Vermeidung von Namenskonflikten und die Unabhängigkeit der Module voneinander.
Problem: Ohne einen einheitlichen Ansatz zur Organisation ist es unmöglich, eine Anwendung zu skalieren; es entstehen Duplizierungen, Namenskonflikte und zyklische Abhängigkeiten. Es ist wichtig, die Sichtbarkeit von Objekten klar zu verfolgen.
Lösung: Jeder Ordner enthält eine Datei mit dem Paket (package somepackage), der Name des Ordners und der Name des Pakets stimmen gemäß den Best Practices überein. Der Import erfolgt über das Schlüsselwort import, und nur Objekte mit einem Großbuchstaben am Anfang werden exportiert. Die Verwaltung von Abhängigkeiten erfolgt über Go-Module (go.mod).
Beispiel für Struktur und Import:
// internal/mathops/add.go package mathops func Add(a, b int) int { return a + b } // main.go package main import ( "fmt" "myservice/internal/mathops" ) func main() { fmt.Println(mathops.Add(2, 3)) }
Schlüsselmerkmale:
Kann man in einem Ordner mehrere verschiedene Pakete deklarieren?
Nein, alle Dateien in einem Ordner müssen zu einem Paket gehören.
Werden Funktionen exportiert, wenn sie einen Namen mit einem Großbuchstaben haben, das Paket aber mit einem Kleinbuchstaben benannt ist?
Ja, der Export hängt nur vom ersten Buchstaben des Objektnamens (Funktion, Typ, Variable) ab, nicht vom Namen des Pakets.
Kann man ein Paket mit einem anderen Alias importieren, und wird das die Sichtbarkeit der Funktionen beeinflussen?
Ja, das ist möglich. Der Alias beeinflusst nur den Namen, unter dem man auf das Paket zugreift, ändert aber nicht die Sichtbarkeit:
import mymath "myservice/internal/mathops" mymath.Add(1,2)
Ein Entwickler packt alle Funktionen in eine Datei "utils.go" im main-Paket, ohne die Geschäftslogik in separate Pakete auszugliedern.
Vorteile:
Nachteile:
Die Geschäftslogik, Utilities, Handler und Datenmodelle wurden in unabhängige Pakete ausgegliedert: mathops, user, storage, api. Der Import erfolgt streng nach Zweck, jedes Paket wird separat getestet.
Vorteile:
Nachteile: