This is a creation in Article, where the information may have evolved or changed.
Preface
Read many aspects of coding specifications, probably each company has different specifications, this code is written to my own, but also hope that our internal colleagues can follow this specification to write go code.
If your code has no way to find the following specifications, then follow the standard library specifications, read more standard library source code, the standard library is a reference to our code can be said to be the benchmark.
Formatting specifications
The go default already has the Gofmt tool, but we strongly recommend using the Goimport tool, which adds automatic deletion and ingestion of packages based on GOFMT.
go get golang.org/x/tools/cmd/goimports
Different editors have different configurations, sublime configuration tutorial: http://michaelwhatcott.com/gosublime-goimports/
Liteide default already supports Goimports, if you do not support click on the property configuration->golangfmt-> tick Goimports
Save your code before automatically fmt.
President's appointment
A line with a maximum of 80 characters, more than the use of line display, try to keep the format elegant.
Go vet
Vet tools can help us to static analysis of our source of various problems, such as redundant code, the logic of early return, the struct's tag compliance standards and so on.
go get golang.org/x/tools/cmd/vet
Use the following:
go vet .
Package Name
Keep the package's name and directory consistent, try to take meaningful packages, short, meaningful, and avoid conflicts with standard libraries.
Import specification
Import in the case of multiple lines, Goimports will automatically help you format, but we still regulate the import of some specifications, if you introduce a package in a file, or the following format is recommended:
import ( "fmt")
If your package introduces three types of packages, standard library packages, program internals, and third-party packages, it is recommended that you organize your packages in the following ways:
import ( "encoding/json" "strings" "myproject/models" "myproject/controller" "myproject/utils" "github.com/astaxie/beego" "github.com/go-sql-driver/mysql")
There are sequential introduction packages, different types are separated by spaces, the first real standard library, the second is the project package, and the third is the third party package.
Do not use relative paths to introduce packages in your project:
// 这是不好的导入import “../net”// 这是正确的做法import “github.com/repo/proj/src/net”
Variable declaration
The name of the variable is the hump standard, do not use _
to name the variable name, multiple variable declarations put together
var ( Found bool count int)
Outside of the function declaration must use VAR, do not adopt :=
, easy to step on the scope of the variable.
String looping issues for custom types
If a custom type defines a string method, some hidden bugs are generated when printing
TypeMyInt IntFunc(MMyInt) String() String { ReturnFmtsprint (m//bug: Dead Loop }func (m myint) string () string {return Fmt. Sprint (int (m //this is safe because we have internally made type conversions }
Avoid returning named arguments
If your function is very short, less than 10 lines of code, then you can use, otherwise please use the type directly, because if using a named variable is very
Easy to cause hidden bugs
func Foo(a int, b int) (string, ok){}
Of course, if more than one parameter of the same type is returned, the named parameter may be clearer:
func (f *Foo) Location() (float64, float64, error)
The following code is clearer:
// Location returns f's latitude and longitude.// Negative values mean south and west, respectively.func (f *Foo) Location() (lat, long float64, err error)
Error handling
The principle of error handling is that you cannot discard any calls that return err, do not _
discard, and must be handled all. Receive an error, either return err, or panic, or log it using log
Error message
Error information do not use uppercase letters, try to keep your mistakes short, but enough to express the meaning of your mistakes.
Long sentences to print or call, use parameters to format a branch
We fmt.Sprint
log.Sprint
sometimes encounter very long sentences when we call or something like that, and we need to do a multiline split at the parameter call:
The following is the wrong way:
Log.Printf(“ALongFormatString: %s %d %d %s Mystringparameter, Len ( a), Expected. Size, Defrobnicate (" Anotherlongstringparameter Expected. Growth. Nanoseconds () /1e6))
Should be the following way:
Log.Printf( “ALongFormatString: %S%d %d %s Mystringparameter, len a Expected.size, Defrobnicate ( "anotherlongstringparameter Expectedgrowth. Nanoseconds ()/1e6, )
Notice the closure of the call
Call a function or Goroutine method in a loop, be sure to use the variable call shown, and do not call the loop parameter inside the closure function.
Fori:=0; I<limit;++{ go func () { Dosomething (i) } () Span class= "PLN" > //error practices go func (i int dosomething ( i) } (i //correct practice }
Http://golang.org/doc/articles/race_detector.html#Race_on_loop_counter
Disabling panic in logical processing
In the main package only if it is not operational, such as panic, such as the file cannot be opened, the database cannot be connected and the program cannot
Normal operation, but for other packages external interface can not have panic, can only be used within the package.
It is strongly recommended that you use log in the main package. Fatal to log errors so that the program can be terminated by log.
Annotation specification
Comments can help us to complete the work of the document well, well-written comments can facilitate our future maintenance. Detailed how to write a comment can be
Reference: Http://golang.org/doc/effective_go.html#commentary
Bug Notes
For bugs that appear in the code, you can use special annotations in the following tutorials, where godocs can be used to highlight annotations:
// BUG(astaxie):This divides by zero. var i float = 1/0
Http://blog.golang.org/2011/03/godocdocumentinggocode.html
struct specification
The struct declaration and initialization format takes multiple lines:
Defined as follows:
type User struct{ Username string Email string}
Initialize as follows:
u := User{ Username: "astaxie", Email: "astaxie@gmail.com",}
Recieved is a value type or a pointer type
Whether to use a value type or a pointer type mainly refer to the following principles:
func(w Win) Tally(playerPlayer)int //w不会有任何改变 func(w *Win) Tally(playerPlayer)int //w会改变数据
For more information, please refer to: Https://code.google.com/p/go-wiki/wiki/CodeReviewComments#Receiver_Type
A struct with a mutex must be a pointer receivers
If you define a struct with a mutex, then your receivers must be a pointer
Resources
- Https://code.google.com/p/go-wiki/wiki/CodeReviewComments
- Http://golang.org/doc/effective_go.html