This is a creation in Article, where the information may have evolved or changed.
* * Note: This document refers to the official guide effective Golang and Golang code Review comments to be organized to align with official and community coding styles.
Gofmt
Most of the formatting problems can be solved by GOFMT, GOFMT automatically format the code, guaranteeing all the go code consistent format.
Normally, when writing go code with sublime, the plug-in Gosublilme has called GOFMT to format the code.
Comments
The variables, functions, and package annotations are written synchronously during the encoding phase, and annotations can be generated from the Godoc export.
The comment must be a complete sentence, starting with the content that needs the comment, and ending with a period.
Each exported (uppercase) name in the program should have a document comment.
Package annotations
Each package should have a package comment, a block comment or a line comment that precedes the packages clause.
Package if you have more than one go file, you only need to appear in a go file.
//Package regexp implements a simple library //for regular expressions.package regexp
Types that can be exported
The first statement should be a summary statement and use the declared name as the starting line.
// Compile parses a regular expression and returns, if successful, a Regexp// object that can be used to match against text.func Compile(str string) (regexp *Regexp, err error) {
Named
With short naming, long names do not automatically make things easier to read, and document annotations are more useful than extra-long names.
Package Name
The package name should be a lowercase word, not underlined or mixed case.
Interface Name
The interface name of a single function is suffixed with "er", such as Reader,writer
The implementation of the interface removes the "ER"
type Reader interface { Read(p []byte) (n int, err error)}
Two functions Interface name synthesis two function names
type WriteFlusher interface { Write([]byte) (int, error) Flush() error}
Interface names of more than three functions, similar to struct names
type Car interface { Start([]byte) Stop() error Recover()}
Mixed case
Use hump-style naming
Mixedcaps capital Start, can be exported mixedcaps lowercase start, non-exportable
Control structure
If
If the initialization statement is accepted, the Convention establishes the local variable as follows
if err := file.Chmod(0664); err != nil { return err}
For
Creating local variables with short declarations
sum := 0for i := 0; i < 10; i++ { sum += i}
Range
If you only need the first item (key), discard the second one:
for key := range m { if key.expired() { delete(m, key) }}
If only the second item is required, place the first item as an underscore
sum := 0for _, value := range array { sum += value}
Return
Return as soon as possible: Once an error occurs, go back immediately
f, err := os.Open(name)if err != nil { return err}d, err := f.Stat()if err != nil { f.Close() return err}codeUsing(f, d)
Function
The function takes a named multi-valued return
Incoming variables and return variables start with lowercase letters
func nextInt(b []byte, pos int) (value, nextPos int) {
In Godoc-generated documents, function declarations with return values are more conducive to understanding
Error handling
Error is returned as the value of the function and must be handled incorrectly if the English must be lowercase and no punctuation ends are required for processing with a separate error stream
Do not use this method
if err != nil { // error handling} else { // normal code}
Instead, use the following method
if err != nil { // error handling return // or continue, etc.}// normal code
If the return value needs to be initialized, use the following method
x, err := f()if err != nil { // error handling return}// use x
Panic
Try not to use panic unless you know what you are doing
Import
Group management of import packages, and the standard library as the first group
package mainimport ( "fmt" "hash/adler32" "os" "appengine/user" "appengine/foo" "code.google.com/p/x/y" "github.com/foo/bar")
Goimports enables automatic formatting of the
Abbreviation
Use all uppercase or lowercase to denote abbreviated words
For example, for the word URL, do not use the UrlPony urlPony 或者 urlpony '
Parameter passing
- For small amounts of data, do not pass pointers
- For structs with large amounts of data, you can consider using pointers
- Incoming parameter is Map,slice,chan do not pass pointer
- Because Map,slice,chan is a reference type, you do not need a pointer to pass the pointer
Accepted by
Name
Unify single letter ' P ' instead of this,me or self
type T struct{} func (p *T)Get(){}
Type
For Go beginners, the type of recipient if not clear, unified use of pointer-type
func (p *T)Get(){}
Instead of
func (p T)Get(){}
In some cases, for performance reasons, or for types that are reference types, there are some exceptions
If the recipient is Map,slice or Chan, do not pass the pointer
//Mappackage mainimport ( "fmt")type mp map[string]stringfunc (m mp) Set(k, v string) { m[k] = v}func main() { m := make(mp) m.Set("k", "v") fmt.Println(m)}//Channelpackage mainimport ( "fmt")type ch chan interface{}func (c ch) Push(i interface{}) { c <- i}func (c ch) Pop() interface{} { return <-c}func main() { c := make(ch, 1) c.Push("i") fmt.Println(c.Pop())}
If you need to modify the slice, re-assign the value by returning the value
//Slicepackage mainimport ( "fmt")type slice []bytefunc main() { s := make(slice, 0) s = s.addOne(42) fmt.Println(s)}func (s slice) addOne(b byte) []byte { return append(s, b)}
If the recipient contains sync. Mutex or a struct similar to a synchronization field, you must use pointer passing to avoid copying
package mainimport ( "sync")type T struct { m sync.Mutex}func (t *T) lock() { t.m.Lock()}/*Wrong !!!func (t T) lock() { t.m.Lock()}*/func main() { t := new(T) t.lock()}
If the recipient is a large struct or array, it is more efficient to pass the pointer.
package mainimport ( "fmt")type T struct { data [1024]byte}func (t *T) Get() byte { return t.data[0]}func main() { t := new(T) fmt.Println(t.Get())}**