Lektionen des Moduls (1/5)
Namenskonventionen und Stil
Go hat starke und nicht verhandelbare Namens- und Stilkonventionen: Der offizielle Formatierer gofmt (und seine Obermenge goimports) entscheidet über Einrückung, Abstand und Importreihenfolge. Die Diskussion über den Stil gilt als nicht zum Thema gehörend: Sie führen gofmt -w aus und fahren fort. Dadurch wird Energie für interessantere Probleme frei.
Sichtbarkeit: Groß- oder Kleinschreibung
Es gibt keine public/private-Schlüsselwörter. Der erste Buchstabe des Namens bestimmt die Sichtbarkeit:
- Großbuchstaben → außerhalb des Pakets exportiert (
User,Login,MaxRetries). - Kleinbuchstaben → privat für das Paket (
user,parseLine,defaultTimeout).
Dies gilt für: Typen, Funktionen, Methoden, Variablen, Konstanten, Strukturfelder.
type User struct {
Name string // exported
email string // private to the package
}Ein „privates“ Strukturfeld wird nicht von encoding/json serialisiert (siehe Modul 8) und ist über Tests in pkg_test nicht zugänglich.
CamelCase, niemals Snake_case
Keine Unterstriche in Namen mit mehreren Wörtern:
- ✅
HTTPClient,userName,parseRequest - ❌
Http_Client,user_name,parse_request
Akronyme werden nur in Großbuchstaben geschrieben (oder nur in Kleinbuchstaben, wenn im privaten Bereich):
- ✅
URL,ID,HTML,JSON,parseURL,userID - ❌
Url,Id,Html,Json,ID0,ID1
type APIResponse struct {
UserID int
HTMLURL string
}Kurznamen für kurze Bereiche
Der Go-Stil bevorzugt Kürze bei gleicher Klarheit in engen Bereichen:
// idiomatic
for i, v := range items { ... }
for k, v := range m { ... }
if err := f(); err != nil { ... }
func (s *Server) Serve(w http.ResponseWriter, r *http.Request) { ... }Etablierte Konventionen:
i, j, kfür Schleifenindizes.vfür Werte,kfür Schlüssel.rfür*Request/io.Reader,wfürWriter/ResponseWriter.errfür Fehler.v0 fürv1.- Methodenempfänger: 1–2 konsistente Buchstaben im gesamten Typ (
v2,v3). Niemalsv4 oderv5.
Je größer der Geltungsbereich, desto aussagekräftiger muss der Name sein: Ein lokaler count ist in Ordnung, aber eine exportierte Count-Variable sollte Ihnen sagen, worauf es ankommt.
Kein „I“-Präfix auf Schnittstellen, kein „Impl“-Suffix
// idiomatic
type Reader interface { ... }
type fileReader struct { ... } // concrete implementation
// not idiomatic
type IReader interface { ... }
type ReaderImpl struct { ... }Kleine Schnittstellen erhalten häufig das Suffix -er: Reader, Writer, Stringer, Closer. Es spiegelt die Tatsache wider, dass sie ein Verhalten beschreiben (idealerweise eine einzelne Methode).
Paketnamen
Ein Paket hat einen einzelnen Namen, kurz, alles in Kleinbuchstaben, keine Unterstriche:
- ✅
bytes,http,os,userauth - ❌
userAuth,user_auth,UserAuth
Der Paketname ist das Verwendungspräfix seiner Symbole: bytes.Buffer, http.Client. Daher ist user.User überflüssig: Besser ist es, den Typ (user.Account) oder das Paket umzubenennen.
gofmt steht nicht zur Debatte
gofmt erzwingt:
- Einrückung mit Tabulatoren (keine Leerzeichen).
- Klammern Sie
{in derselben Zeile wie die Signatur ein. - Importe in Gruppen, getrennt durch eine Leerzeile;
goimportsfügt auch fehlende Importe hinzu. - Leerzeichen um Operatoren.
Führen Sie vor dem Commit immer Folgendes aus:
go fmt ./...
goimports -w .
go vet ./...Linters (staticcheck, golangci-lint) fügen zusätzliche Regeln hinzu (nicht verwendete Variablen, Schatten, nutzlose Vergleiche, ...).
Übungen
Fügen Sie die Struktur Http_Client in HTTPClient hinzu (und die URL in der URL), und folgen Sie den Konventionen. Gehen Sie zu Ihren Akronymen.
Lösung nach 3 Versuchen verfügbar
Sichtbarkeit umkehren: Benutzername (mehrfarbig) und privates Passwort (minus) eingeben.
Lösung nach 3 Versuchen verfügbar
Welcher Name ist Go für einen Typ, der „HTTP-Server“ exportiert?
type ??? struct {}