Master Go Naming: Consistent, Concise, and Precise Conventions
Effective naming in Go requires consistency, brevity, and precision, with guidelines covering variable and function names, camel‑case conventions, short local variables, descriptive parameters, return values, method receivers, package naming, interface naming, and error types, illustrated by numerous code examples from the standard library.
Excellent Naming
Excellent naming should be consistent, short, and precise. Consistency means the same meaning must have the same name across contexts, e.g., avoid using both
dependand
rely. Shortness prevents the reader from being distracted by overly long identifiers, and precision makes the name clear and easy to understand.
First Rule
The farther the declaration location is from its usage, the longer the name should be.
CamelCase Naming
Go code should use MixedCase (camel case) and avoid
names_with_underscores. Acronyms should be capitalized, for example
ServeHTTP,
sceneID,
CIDRProcessor.
Local Variables
Local variables should be as short as possible, e.g.,
buffor a buffer,
ifor an index. In very long functions many variables may need longer names, which usually indicates the function should be refactored.
Parameters
Function parameters act like documentation. When the parameter type is descriptive, the name should be kept short.
<code>func AfterFunc(d Duration, f func()) *Timer
func Escape(w io.Writer, s []byte)</code>If the parameter type is vague, the name should convey documentation purpose.
Return Values
In Go, return values can be named and treated as special parameters. For exported functions, the names should serve as documentation references.
Method Receivers
Method receivers are also special parameters. Although Go lacks explicit object‑oriented syntax, receivers give methods a pseudo‑object feel. By convention, receivers are usually a single or a couple of letters that indicate the type.
<code>func (b *Buffer) Read(p []byte) (n int, err error)
func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request)
func (r Rectangle) Size() Point</code>Receiver names should be consistent across methods of the same type.
Exported Package Naming
Exported names are used after the package name, so do not repeat the package meaning. Good examples:
bytes.Buffer,
strings.Reader. Poor examples:
bytes.ByteBuffer,
strings.StringReader.
Interface Types
Interfaces with a single method often use the method name plus the
ersuffix, e.g.,
Reader. For multi‑method interfaces, choose a name that precisely describes the purpose, such as
net.Connor
http.ResponseWriter.
<code>type Reader interface { Read(p []byte) (n int, err error) }
type Execer interface { Exec(p []byte) (n int, err error) }
type ByteReader interface { ReadByte(p []byte) (n int, err error) }</code>Error Naming
Error types should be named
FooError. Error variables often follow the pattern
ErrFoo.
<code>type ExitError struct { /* fields */ }</code>Package Naming
A package name should reflect its exported content and avoid generic names like
utilor
common. The last segment of the import path should match the package name, be concise, and avoid uppercase letters.
Import Paths
Import paths should be short, with the final element identical to the package name, and the main code should reside at the repository root.
Standard Library
Many of the examples are drawn from the Go standard library, which is a valuable source of naming inspiration. Remember that even standard library authors can make occasional mistakes.
<code>var ErrFormat = errors.New("unknown format")
func Copy(dst Writer, src Reader) (written int64, err error)
func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error)
func Unix(sec, nsec int64) Time
func HasPrefix(s, prefix []byte) bool</code>Raymond Ops
Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.