开源软件名称: cristaloleg/go-advice开源软件地址: https://github.com/cristaloleg/go-advice开源编程语言:
Go
100.0%
开源软件介绍: Go-advice
(Some of advices are implemented in go-critic )
Contents
Go Proverbs
Don't communicate by sharing memory, share memory by communicating.
Concurrency is not parallelism.
Channels orchestrate; mutexes serialize.
The bigger the interface, the weaker the abstraction.
Make the zero value useful.
interface{}
says nothing.
Gofmt's style is no one's favorite, yet gofmt is everyone's favorite.
A little copying is better than a little dependency.
Syscall must always be guarded with build tags.
Cgo must always be guarded with build tags.
Cgo is not Go.
With the unsafe package there are no guarantees.
Clear is better than clever.
Reflection is never clear.
Errors are values.
Don't just check errors, handle them gracefully.
Design the architecture, name the components, document the details.
Documentation is for users.
Don't panic.
Author: Rob Pike
See more: https://go-proverbs.github.io/
The Zen of Go
Each package fulfils a single purpose
Handle errors explicitly
Return early rather than nesting deeply
Leave concurrency to the caller
Before you launch a goroutine, know when it will stop
Avoid package level state
Simplicity matters
Write tests to lock in the behaviour of your package’s API
If you think it’s slow, first prove it with a benchmark
Moderation is a virtue
Maintainability counts
Author: Dave Cheney
See more: https://the-zen-of-go.netlify.com/
Code
Always go fmt
your code.
Community uses the official Go format, do not reinvent the wheel.
Try to reduce code entropy. This will help everyone to make code easy to read.
Multiple if-else statements can be collapsed into a switch
// NOT BAD
if foo () {
// ...
} else if bar == baz {
// ...
} else {
// ...
}
// BETTER
switch {
case foo ():
// ...
case bar == baz :
// ...
default :
// ...
}
To pass a signal prefer chan struct{}
instead of chan bool
.
When you see a definition of chan bool
in a structure, sometimes it's not that easy to understand how this value will be used, example:
type Service struct {
deleteCh chan bool // what does this bool mean?
}
But we can make it more clear by changing it to chan struct{}
which explicitly says: we do not care about value (it's always a struct{}
), we care about an event that might occur, example:
type Service struct {
deleteCh chan struct {} // ok, if event than delete something.
}
Prefer 30 * time.Second
instead of time.Duration(30) * time.Second
You don't need to wrap untyped const in a type, compiler will figure it out. Also prefer to move const to the first place:
// BAD
delay := time .Second * 60 * 24 * 60
// VERY BAD
delay := 60 * time .Second * 60 * 24
// GOOD
delay := 24 * 60 * 60 * time .Second
// EVEN BETTER
delay := 24 * time .Hour
Use time.Duration
instead of int64
+ variable name
// BAD
var delayMillis int64 = 15000
// GOOD
var delay time.Duration = 15 * time .Second
Group const
declarations by type and var
by logic and/or type
// BAD
const (
foo = 1
bar = 2
message = "warn message"
)
// MOSTLY BAD
const foo = 1
const bar = 2
const message = "warn message"
// GOOD
const (
foo = 1
bar = 2
)
const message = "warn message"
This pattern works for var
too.
defer func () {
err := ocp .Close ()
if err != nil {
rerr = err
}
}()
package main
type Status = int
type Format = int // remove `=` to have type safety
const A Status = 1
const B Format = 1
func main () {
println (A == B )
}
func f (a int , _ string ) {}
func f (a int , b int , s string , p string )
func f (a , b int , s , p string )
var s []int
fmt .Println (s , len (s ), cap (s ))
if s == nil {
fmt .Println ("nil!" )
}
// Output:
// [] 0 0
// nil!
var a []string
b := []string {}
fmt .Println (reflect .DeepEqual (a , []string {}))
fmt .Println (reflect .DeepEqual (b , []string {}))
// Output:
// false
// true
value := reflect .ValueOf (object )
kind := value .Kind ()
if kind >= reflect .Chan && kind <= reflect .Slice {
// ...
}
func f1 () {
var a , b struct {}
print (& a , "\n " , & b , "\n " ) // Prints same address
fmt .Println (& a == & b ) // Comparison returns false
}
func f2 () {
var a , b struct {}
fmt .Printf ("%p\n %p\n " , & a , & b ) // Again, same address
fmt .Println (& a == & b ) // ...but the comparison returns true
}
const (
_ = iota
testvar // will be int
)
vs
type myType int
const (
_ myType = iota
testvar // will be myType
)
Don’t use encoding/gob
on structs you don’t own.
At some point structure may change and you might miss this. As a result this might cause a hard to find bug.
Don't depend on the evaluation order, especially in a return statement.
// BAD
return res , json .Unmarshal (b , & res )
// GOOD
err := json .Unmarshal (b , & res )
return res , err
To prevent unkeyed literals add _ struct{}
field:
type Point struct {
X , Y float64
_ struct {} // to prevent unkeyed literals
}
For Point{X: 1, Y: 1}
everything will be fine, but for Point{1,1}
you will get a compile error:
./file.go:1:11: too few values in Point literal
There is a check in go vet
command for this, there is no enough arguments to add _ struct{}
in all your structs.
To prevent structs comparison add an empty field of func
type
type Point struct {
_ [0 ]func () // unexported, zero-width non-comparable field
X , Y float64
}
Prefer http.HandlerFunc
over http.Handler
To use the 1st one you just need a func, for the 2nd you need a type.
Move defer
to the top
This improves code readability and makes clear what will be invoked at the end of a function.
JavaScript parses integers as floats and your int64 might overflow.
Use json:"id,string"
instead.
type Request struct {
ID int64 `json:"id,string"`
}
Concurrency
Performance
b := a [:0 ]
for _ , x := range a {
if f (x ) {
b = append (b , x )
}
}
To help compiler to remove bound checks see this pattern _ = b[7]
res , _ := client .Do (req )
io .Copy (ioutil .Discard , res .Body )
defer res .Body .Close ()
ticker := time .NewTicker (1 * time .Second )
defer ticker .Stop ()
func (entry Entry ) MarshalJSON () ([]byte , error ) {
buffer := bytes .NewBufferString ("{" )
first := true
for key , value := range entry {
jsonValue , err := json .Marshal (value )
if err != nil {
return nil , err
}
if ! first {
buffer .WriteString ("," )
}
first = false
buffer .WriteString (key + ":" + string (jsonValue ))
}
buffer .WriteString ("}" )
return buffer .Bytes (), nil
}
// noescape hides a pointer from escape analysis. noescape is
// the identity function but escape analysis doesn't think the
// output depends on the input. noescape is inlined and currently
// compiles down to zero instructions.
func noescape (p unsafe.Pointer ) unsafe.Pointer {
x := uintptr (p )
return unsafe .Pointer (x ^ 0 )
}
for k := range m {
delete (m , k )
}
Modules
Build
Testing
func TestSomething (t * testing.T ) {
if testing .Short () {
t .Skip ("skipping test in short mode." )
}
}
if runtime .GOARM == "arm" {
t .Skip ("this doesn't work under ARM" )
}
Tools
quick replace gofmt -w -l -r "panic(err) -> log.Error(err)" .
go list
allows to find all direct and transitive dependencies
go list -f '{{ .Imports }}' package
go list -f '{{ .Deps }}' package
for fast benchmark comparison we've a benchstat
tool
go-critic linter enforces several advices from this document
go mod why -m <module>
tells us why a particular module is in the go.mod
file
GOGC=off go build ...
should speed up your builds source
六六分期app的软件客服如何联系?不知道吗?加qq群【895510560】即可!标题:六六分期
阅读:18053| 2023-10-27
今天小编告诉大家如何处理win10系统火狐flash插件总是崩溃的问题,可能很多用户都不知
阅读:9603| 2022-11-06
今天小编告诉大家如何对win10系统删除桌面回收站图标进行设置,可能很多用户都不知道
阅读:8144| 2022-11-06
今天小编告诉大家如何对win10系统电脑设置节能降温的设置方法,想必大家都遇到过需要
阅读:8527| 2022-11-06
我们在使用xp系统的过程中,经常需要对xp系统无线网络安装向导设置进行设置,可能很多
阅读:8429| 2022-11-06
今天小编告诉大家如何处理win7系统玩cf老是与主机连接不稳定的问题,可能很多用户都不
阅读:9335| 2022-11-06
电脑对日常生活的重要性小编就不多说了,可是一旦碰到win7系统设置cf烟雾头的问题,很
阅读:8393| 2022-11-06
我们在日常使用电脑的时候,有的小伙伴们可能在打开应用的时候会遇见提示应用程序无法
阅读:7829| 2022-11-06
今天小编告诉大家如何对win7系统打开vcf文件进行设置,可能很多用户都不知道怎么对win
阅读:8381| 2022-11-06
今天小编告诉大家如何对win10系统s4开启USB调试模式进行设置,可能很多用户都不知道怎
阅读:7377| 2022-11-06
请发表评论