Golang 常用的 checkstyle 有 golangci-lint 和 golint, 今天我们主要介绍 golangci-lint, golangci-lint 用于许多开源项目中, 比如 kubernetes、Prometheus、TiDB 等都使用 golangci-lint 用于代码检查, TIDB 的 makefile 中的 check-static 使用 golangci-lint 进行代码检查, 可参考: https://github.com/pingcap/tidb/blob/master/Makefile
源码地址: https://github.com/golangci/golangci-lint
安装及使用: https://golangci-lint.run/
golangci-lint run
等同于 golangci-lint run ./...
golangci-lint run dir1 dir2/... dir3/file1.go`
检查 dir1 和 dir2 目录下的代码及 dir3 目录下的 file1.go 文件
--enable/-E
开启指定 Linter, 也可以通 --disable/-D
关闭指定 Linter有的时候会需要禁用 lint 检查, 可以在需要禁用检测的函数或者语句附近这样使用:
//nolint:lll,funlen
[[issues.exclude-rules]]
path = "(.+)_test.go"
linters = ["typecheck"]
text = "imported but not used"
Linters 是代码检查的项, 默认开启的 Linters 如下:
还有许多默认没有开启的 Linter, 可以通过 —enable 开启默认未开启的 Linter。
比如:
err = errors.New(fmt.Sprintf("%s", val))
代码检查会直接推荐你使用 fmt.Errorf(...)
strChan := make(chan string,0)
代码检查会提示你直接使用 make(chan string)
示例:
var index byte = 0
以上代码会提示 ineffectual assignment to index
(无效的分配, 因为 index 的默认值为 0)
示例:
fmt.Errorf("%s", val)
有声明但没有使用loopclosure: loop variable xxx captured by func literal (govet)
某个方法中重复定义了相同的局部变量finds type assertions which did forcely such as below.
func f() {
var a interface{}
_ = a.(int) // type assertion must be checked
}
You need to check if the assertion failed like so:
func f() {
var a interface{}
_, ok := a.(int)
if !ok { // type assertion failed
// handle error
}
}
Yoda conditions are conditions of the kind if 42 == x
, where the literal is on the left side of the comparison. These are a common idiom in languages in which assignment is an expression, to avoid bugs of the kind if (x = 42)
. In Go, which doesn’t allow for this kind of bug, we prefer the more idiomatic if x == 42
.
Available since
2019.2
import math/rand
改为 crypto/rand
。
...
) to avoid escaping twiceregex := regexp.MustCompile("(\\d+)")
=>
regex := regexp.MustCompile(`(\d+)`)
Your code is copying sync.Map
values, which is forbidden:
A Map must not be copied after first use.