Module lessons (1/5)
Naming conventions and style
Go has strong and non-negotiable naming and style conventions: the official formatter gofmt (and its superset goimports) decides indentation, spacing, and import order. Discussing style is considered off-topic: you run gofmt -w and move on. This frees up energy for more interesting problems.
Visibility: uppercase or lowercase
There are no public/private keywords. The first letter of the name determines visibility:
- Uppercase → exported outside the package (
User,Login,MaxRetries). - Lowercase → private to the package (
user,parseLine,defaultTimeout).
This applies to: types, functions, methods, variables, constants, struct fields.
type User struct {
Name string // exported
email string // private to the package
}A "private" struct field is not serialized by encoding/json (see Module 8), and it is not accessible from tests in pkg_test.
CamelCase, never snake_case
No underscores in multi-word names:
- ✅
HTTPClient,userName,parseRequest - ❌
Http_Client,user_name,parse_request
Acronyms go all uppercase (or all lowercase, if in private scope):
- ✅
URL,ID,HTML,JSON,parseURL,userID - ❌
Url,Id,Html,Json,parseUrl,userId
type APIResponse struct {
UserID int
HTMLURL string
}Short names for short scopes
Go style favors brevity at equal clarity in narrow 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) { ... }Established conventions:
i, j, kfor loop indices.vfor values,kfor keys.rfor*Request/io.Reader,wforWriter/ResponseWriter.errfor errors.ctxforcontext.Context.- Method receivers: 1–2 consistent letters across the whole type (
s *Server,u *User). Neverthisorself.
The wider the scope, the more descriptive the name must become: a local count is fine, but an exported Count variable should tell you what it counts.
No "I" prefix on interfaces, no "Impl" suffix
// idiomatic
type Reader interface { ... }
type fileReader struct { ... } // concrete implementation
// not idiomatic
type IReader interface { ... }
type ReaderImpl struct { ... }Small interfaces often take the -er suffix: Reader, Writer, Stringer, Closer. It echoes the fact that they describe a behavior (a single method, ideally).
Package names
A package has a single name, short, all lowercase, no underscores:
- ✅
bytes,http,os,userauth - ❌
userAuth,user_auth,UserAuth
The package name is the usage prefix of its symbols: bytes.Buffer, http.Client. So user.User is redundant: better to rename the type (user.Account) or the package.
gofmt is not up for debate
gofmt enforces:
- Indentation with tabs (not spaces).
- Brace
{on the same line as the signature. - Imports in groups separated by a blank line;
goimportsalso adds missing imports. - Spaces around operators.
Always run before committing:
go fmt ./...
goimports -w .
go vet ./...Linters (staticcheck, golangci-lint) add extra rules (unused variables, shadowing, useless comparisons, ...).
Exercises
Rinomina la struct Http_Client in HTTPClient (e il campo Url in URL) seguendo le convenzioni Go sugli acronimi.
Solution available after 3 attempts
Inverti la visibilità: rendi Username esportato (maiuscolo) e password privato (minuscolo).
Solution available after 3 attempts
Quale di questi nomi è idiomatico in Go per un tipo esportato 'server HTTP'?
type ??? struct {}