Modulelessen (1/5)
Naamgevingsconventies en stijl
Go heeft sterke en niet-onderhandelbare naamgevings- en stijlconventies: de officiële formatter gofmt (en zijn superset goimports) bepaalt de inspringing, spatiëring en importvolgorde. De discussiestijl wordt als off-topic beschouwd: je voert gofmt -w uit en gaat verder. Dit maakt energie vrij voor interessantere problemen.
Zichtbaarheid: hoofdletters of kleine letters
Er zijn geen public/private zoekwoorden. De eerste letter van de naam bepaalt de zichtbaarheid:
- Hoofdletters → geëxporteerd buiten het pakket (
User,Login,MaxRetries). - Kleine letters → privé voor het pakket (
user,parseLine,defaultTimeout).
Dit geldt voor: typen, functies, methoden, variabelen, constanten, structvelden.
type User struct {
Name string // exported
email string // private to the package
}Een "privé" struct-veld is niet geserialiseerd door encoding/json (zie Module 8), en is niet toegankelijk via tests in pkg_test.
CamelCase, nooit snake_case
Geen onderstrepingstekens in namen die uit meerdere woorden bestaan:
- ✅
HTTPClient,userName,parseRequest - ❌
Http_Client,user_name,parse_request
Acroniemen zijn allemaal in hoofdletters (of allemaal in kleine letters, indien in privébereik):
- ✅
URL,ID,HTML,JSON,parseURL,userID - ❌
Url,Id,Html,Json,parseUrl,userId
type APIResponse struct {
UserID int
HTMLURL string
}Korte namen voor korte scopes
Go-stijl is voorstander van beknoptheid en gelijke helderheid in smalle scopes:
// 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) { ... }Gevestigde conventies:
i, j, kvoor lusindices.vvoor waarden,kvoor sleutels.rvoor*Request/io.Reader,wvoorWriter/ResponseWriter.errvoor fouten.ctxvoorcontext.Context.- Methodeontvangers: 1-2 consistente letters over het hele type (
s *Server,u *User). Nooitthisofself.
Hoe breder de reikwijdte, hoe beschrijvender de naam moet worden: een lokale count is prima, maar een geëxporteerde Count variabele zou je moeten vertellen wat deze telt.
Geen "I"-voorvoegsel op interfaces, geen "Impl"-achtervoegsel
// idiomatic
type Reader interface { ... }
type fileReader struct { ... } // concrete implementation
// not idiomatic
type IReader interface { ... }
type ReaderImpl struct { ... }Kleine interfaces hebben vaak het achtervoegsel -er: Reader, Writer, Stringer, Closer. Het weerspiegelt het feit dat ze een gedrag beschrijven (idealiter één enkele methode).
Pakketnamen
Een pakket heeft één enkele naam, kort, allemaal kleine letters, geen onderstrepingstekens:
- ✅
bytes,http,os,userauth - ❌
userAuth,user_auth,UserAuth
De pakketnaam is het gebruiksvoorvoegsel van de symbolen: bytes.Buffer, http.Client. Dus user.User is overbodig: het is beter om het type (user.Account) of het pakket te hernoemen.
gofmt staat niet ter discussie
gofmt dwingt af:
- Inspringen met tabs (geen spaties).
- Zet
{op dezelfde regel als de handtekening. - Importeert in groepen gescheiden door een witregel;
goimportsvoegt ook ontbrekende importen toe. - Ruimtes rondom operators.
Voer altijd uit voordat u een commit maakt:
go fmt ./...
goimports -w .
go vet ./...Linters (staticcheck, golangci-lint) voegen extra regels toe (ongebruikte variabelen, schaduwen, nutteloze vergelijkingen, ...).
Oefeningen
Geef de structuur van Http_Client in HTTPClient weer (en de URL van de URL in URL) en ga vervolgens naar de volgende acronimi.
Oplossing beschikbaar na 3 pogingen
Verander de zichtbaarheid: geef de gebruikersnaam esportato (maiuscolo) en het privéwachtwoord (minuscolo) weer.
Oplossing beschikbaar na 3 pogingen
Welke vraag is het idiomatisch in het gebruik van een soort 'server HTTP'?
type ??? struct {}