5.1 KiB
Variables, Booleans, Receivers & Acronyms
Variables
Name length SHOULD be proportional to scope size. Short names for small scopes, descriptive names for large scopes.
// Small scope (1-7 lines): short names are fine
for i, v := range items {
result = append(result, v.Name)
}
// Medium scope: moderately descriptive
userCount := len(users)
// Large scope / package-level: explicit and clear
var defaultHTTPTransport = &http.Transport{
MaxIdleConns: 100,
}
Common single-letter conventions:
| Letter | Meaning |
|---|---|
i, j, k |
Loop indices |
n |
Count or length |
v |
Value (in range loops) |
k |
Key (in map ranges) |
r |
io.Reader |
w |
io.Writer |
b |
[]byte or buffer |
s |
String |
t |
*testing.T |
ctx |
context.Context |
err |
Error |
Avoid Type in the Name
The name should describe what the value represents, not its type.
// Good
users := getUsers()
count := len(items)
// Bad
userSlice := getUsers()
countInt := len(items)
nameString := "hello"
Avoid Repetition with Context
Omit words already clear from the enclosing function, method, or type.
// Good — "user" is clear from the method receiver
func (u *UserService) Create(name string) error { ... }
// Bad — "user" is redundant
func (u *UserService) CreateUser(userName string) error { ... }
Use Predictable Names
The same concept MUST always use the same name across the codebase. If a user is called user in one function, it should not become account, person, or u in another. Consistency makes code searchable and reduces cognitive load.
// Good — same concept, same name everywhere
func CreateUser(user *User) error { ... }
func UpdateUser(user *User) error { ... }
func DeleteUser(userID string) error { ... }
// Bad — same concept, different names
func CreateUser(user *User) error { ... }
func UpdateAccount(acct *User) error { ... } // why "acct"? it's a User
func RemovePerson(id string) error { ... } // why "person"? why "remove"?
This applies to variables, parameters, functions, and fields. Pick one name per domain concept and stick with it: order not sometimes order / sometimes purchase; userID not sometimes userID / sometimes uid / sometimes userId.
Parameters
Parameters double as documentation at the call site. When the type is descriptive, keep the name short. When the type is ambiguous, use a longer name to clarify intent.
// Good — type is descriptive, short name is fine
func AfterFunc(d Duration, f func()) *Timer
func Escape(w io.Writer, s []byte)
// Good — type is ambiguous (int64, string), longer name documents meaning
func Unix(sec, nsec int64) Time
func HasPrefix(s, prefix string) bool
// Bad — ambiguous type with cryptic name
func Unix(a, b int64) Time // what are a and b?
func HasPrefix(a, b string) bool // which is the prefix?
Booleans
Boolean variables and fields MUST read naturally as true/false questions. Use prefixes like is, has, can, allow, should. This applies to both variables and struct fields.
// Good — struct fields use is/has prefix
type Client struct {
isConnected bool // reads as "client is connected"
hasPermission bool // reads as "client has permission"
}
// Good — variables
isReady := true
hasPermission := user.CanEdit(doc)
// Bad — bare adjective is ambiguous
type Client struct {
connected bool // could be confused with a connection object
permission bool // noun, not a question
}
For exported boolean methods, the prefix becomes part of the method name: IsValid(), HasPrefix(), CanRetry(). The unexported field keeps the prefix too: isConnected field → IsConnected() method.
Receivers
Receivers MUST be 1-2 letter abbreviations of the type name. Use the same name across all methods of a type.
// Good — short, consistent
func (s *Server) Start() error { ... }
func (s *Server) Stop() error { ... }
func (s *Server) Handle(r *Request) { ... }
// Bad — too long
func (server *Server) Start() error { ... }
// Bad — inconsistent names across methods
func (s *Server) Start() error { ... }
func (srv *Server) Stop() error { ... }
// Bad — NEVER use "this" or "self"
func (this *Server) Handle(r *Request) { ... }
Acronyms and Initialisms
Acronyms MUST be all caps or all lower, NEVER mixed. This preserves readability in MixedCaps names.
// Good
URL // all caps
url // all lower
HTTPServer // HTTP is all caps
xmlParser // xml is all lower
userID // ID is all caps
newHTTPSURL // both HTTPS and URL all caps
// Bad
Url // mixed case acronym
HttpServer // mixed case
userId // mixed case for ID
When exporting a lowercase acronym, capitalize the whole thing: url → URL, grpc → GRPC, ios → IOS.