golangci-lint

1. golangci-lint

1.1. golangci-lint

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/

1.1.1. golangci-lint 使用

  1. 检查当前目录下所有的文件

golangci-lint run 等同于 golangci-lint run ./...

  1. 可以指定某个目录和文件
golangci-lint run dir1 dir2/... dir3/file1.go`

检查 dir1 和 dir2 目录下的代码及 dir3 目录下的 file1.go 文件

  1. 可以通过 --enable/-E 开启指定 Linter, 也可以通 --disable/-D 关闭指定 Linter

1.1.2. 禁用 lint 检查

有的时候会需要禁用 lint 检查, 可以在需要禁用检测的函数或者语句附近这样使用:

//nolint:lll,funlen
1.1.2.1. 在配置里面禁用
[[issues.exclude-rules]]
path = "(.+)_test.go"
linters = ["typecheck"]
text = "imported but not used"

1.2. Linter

Linters 是代码检查的项, 默认开启的 Linters 如下:

还有许多默认没有开启的 Linter, 可以通过 —enable 开启默认未开启的 Linter。

1.2.1. 常用的 Linter 介绍

  • deadcode 未使用且未导出的函数 (比如: 首字母小写且未被调用的方法)
  • errcheck 返回的 error 未处理
  • structcheck 检测结构体中未使用的字段
  • unused 方法中方法名首字母小写 (未导出) 并且未使用的方法
  • gosimple 代码中有需要优化的地方

比如:

  1. err = errors.New(fmt.Sprintf("%s", val)) 代码检查会直接推荐你使用 fmt.Errorf(...)
  2. strChan := make(chan string,0) 代码检查会提示你直接使用 make(chan string)
  3. select 中只有一个 case 代码检查会提示你去掉 select
  • ineffassign: 检测变量的赋值

示例:

var index byte = 0

以上代码会提示 ineffectual assignment to index(无效的分配, 因为 index 的默认值为 0)

  • govet: 用于检测代码结构中可以的构造

示例:

  1. fmt.Errorf("%s", val) 有声明但没有使用
  2. loopclosure: loop variable xxx captured by func literal (govet) 某个方法中重复定义了相同的局部变量

1.3. golang lint 错误解决

1.3.1. type assertion must be checked

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
	}
}

1.3.2. ST1017 – Don’t use Yoda conditions

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

1.3.3. G404: Use of weak random number generator (math/rand instead of crypto/rand)

import math/rand 改为 crypto/rand

1.3.4. S1007 use raw string (...) to avoid escaping twice

regex := regexp.MustCompile("(\\d+)")

=>

regex := regexp.MustCompile(`(\d+)`)

1.3.5. copylocks: literal copies lock value from dynamicDevices: sync.Map contains sync.Mutex (govet)

Your code is copying sync.Map values, which is forbidden:

A Map must not be copied after first use.

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云满笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值