Naming convention
Interface names
By convention, one-method interfaces are named by the method name plus an -er suffix or similar modification to construct an agent noun: Reader, Writer, Formatter, CloseNotifier etc.
MixedCaps
Finally, the convention in Go is to use MixedCaps or mixedCaps rather than underscores to write multiword names.
Getters
It's neither idiomatic nor necessary to put Get into the getter's name. If you have a field called owner (lower case, unexported), the getter method should be called Owner (upper case, exported), not GetOwner. The use of upper-case names for export provides the hook to discriminate the field from the method. A setter function, if needed, will likely be called SetOwner. Both names read well in practice:
owner := obj.Owner()
if owner != user {
obj.SetOwner(user)
}
They even have semantic effect: the visibility of a name outside a package is determined by whether its first character is upper case.
Package names ¶
When a package is imported, the package name becomes an accessor for the contents. After
import "bytes"
the importing package can talk about bytes.Buffer. It's helpful if everyone using the package can use the same name to refer to its contents, which implies that the package name should be good: short, concise, evocative. By convention, packages are given lower case, single-word names; there should be no need for underscores or mixedCaps. Another convention is that the package name is the base name of its source directory; the package in src/encoding/base64 is imported as "encoding/base64" but has name base64, not encoding_base64 and not encodingBase64.
The importer of a package will use the name to refer to its contents, For instance, the buffered reader type in the bufio package is called Reader, not BufReader, because users see it as bufio.Reader, which is a clear, concise name. Moreover, because imported entities are always addressed with their package name, bufio.Reader does not conflict with io.Reader. Similarly, the function to make new instances of ring.Ring—which is the definition of a constructor in Go—would normally be called NewRing, but since Ring is the only type exported by the package, and since the package is called ring, it's called just New, which clients of the package see as ring.New. Use the package structure to help you choose good names.
Another short example is once.Do; once.Do(setup) reads well and would not be improved by writing once.DoOrWaitUntilDone(setup).
The gofmt program (also available as go fmt, which operates at the package level rather than source file level) reads a Go program and emits the source in a standard style of indentation and vertical alignment, retaining and if necessary reformatting comments. If you want to know how to handle some new layout situation, run gofmt; if the answer doesn't seem right, rearrange your program (or file a bug about gofmt), don't work around it.
As an example, there's no need to spend time lining up the comments on the fields of a structure. Gofmt will do that for you. Given the declaration
type T struct {
name string // name of the object
value int // its value
}
gofmt will line up the columns:
type T struct {
name string // name of the object
value int // its value
}
All Go code in the standard packages has been formatted with gofmt.
Some formatting details remain. Very briefly:
- Indentation
- We use tabs for indentation and
gofmtemits them by default. Use spaces only if you must. - Line length
- Go has no line length limit. Don't worry about overflowing a punched card. If a line feels too long, wrap it and indent with an extra tab.
- Parentheses
- Go needs fewer parentheses than C and Java: control structures (
if,for,switch) do not have parentheses in their syntax. Also, the operator precedence hierarchy is shorter and clearer, sox<<8 + y<<16
means what the spacing implies, unlike in the other languages. When a package is imported, the package name becomes an accessor for the contents. After
import "bytes"
the importing package can talk about
bytes.Buffer. It's helpful if everyone using the package can use the same name to refer to its contents, which implies that the package name should be good: short, concise, evocative. By convention, packages are given lower case, single-word names; there should be no need for underscores or mixedCaps.Another convention is that the package name is the base name of its source directory; the package in
src/encoding/base64is imported as"encoding/base64"but has namebase64, notencoding_base64and notencodingBase64.The importer of a package will use the name to refer to its contents, For instance, the buffered reader type in the
bufiopackage is calledReader, notBufReader, because users see it asbufio.Reader, which is a clear, concise name. Moreover, because imported entities are always addressed with their package name,bufio.Readerdoes not conflict withio.Reader. Similarly, the function to make new instances ofring.Ring—which is the definition of a constructor in Go—would normally be calledNewRing, but sinceRingis the only type exported by the package, and since the package is calledring, it's called justNew, which clients of the package see asring.New. Use the package structure to help you choose good names.Another short example is
once.Do;once.Do(setup)reads well and would not be improved by writingonce.DoOrWaitUntilDone(setup). Long names don't automatically make things more readable.Go's declaration syntax allows grouping of declarations. A single doc comment can introduce a group of related constants or variables. // Error codes returned by failures to parse an expression.
var ( ErrInternal = errors.New("regexp: internal error") ErrUnmatchedLpar = errors.New("regexp: unmatched '('") ErrUnmatchedRpar = errors.New("regexp: unmatched ')'") ... )Grouping can also indicate relationships between items, such as the fact that a set of variables is protected by a mutex.
var ( countLock sync.Mutex inputCount uint32 outputCount uint32 errorCount uint32 )
Comments
Post a Comment