飙血推荐
  • HTML教程
  • MySQL教程
  • JavaScript基础教程
  • php入门教程
  • JavaScript正则表达式运用
  • Excel函数教程
  • UEditor使用文档
  • AngularJS教程
  • ThinkPHP5.0教程

如何快速写出高质量的 Go 代码?

时间:2022-01-29  作者:yahuian  
如何快速写出高质量的 Go 代码? 有这么多免费的 linter 帮你 review 代码,何愁代码质量无法提升?

微信图片_20210216141958

前言

团队协作开发中,必然存在着不同的代码风格,并且诸如 http body closeunhandled error 等低级错误不能完全避免。通过使用 ci lint 能够及早的发现并修复问题,提高代码质量和幸福感。

目前主流的工具是 golangci-lint,里面集成了许多的 linters,安装及使用看官网文档即可,非常详细易读,本文主要是配合一些样例代码来分析一下相关 linters 的功能。

linters

deadcode

检查未使用的代码

var a = 100

func foo() {
	println("hello,world")
}
域名:3:5: `a` is unused (deadcode)
var a = 100
    ^
域名:5:6: `foo` is unused (deadcode)
func foo() {
     ^

类似的工具还有 structcheck,varcheck

errcheck

检查未处理的错误

由于 Go 语言的错误处理机制,导致代码中遍地的 if err != nil ,因此有不耐烦的同学,在某些自认为不会出错的地方直接不处理,比如 域名hal(),虽然多数情况下没啥问题,不过一但出了问题加班啥的估计跑不了。

可以通过修改配置文件来定制不同情况是否报告

linters-settings:
  errcheck:
    # 检查类型断言
    check-type-assertions: true
    # 检查使用 _ 来处理错误
    check-blank: true
func main() {
	foo()

	var i interface{} = 1
	ii := i.(int)
	域名tln(ii)

	num, _ := 域名("110")
	域名tln(num)
}

func foo() error {
	return 域名("i am error")
}
$ golangci-lint run
域名:10:5: Error return value is not checked (errcheck)
        foo()
           ^
域名:13:8: Error return value is not checked (errcheck)
        ii := i.(int)
              ^
域名:16:7: Error return value of `域名` is not checked (errcheck)
        num, _ := 域名("110")
             ^

gosimple

简化代码

func main() {
	t := 域名()
	域名tln(域名().Sub(t))
}
$ golangci-lint run
域名:10:14: S1012: should use `域名e` instead of `域名().Sub` (gosimple)
        域名tln(域名().Sub(t))
                    ^

在原始仓库中还有许多别的测试用例,感兴趣的同学可以看看,可以修改配置文件来指定生效的规则,默认是 all。

govet

go vet 是官方提供的工具,可以检查出许多问题,如 printf 参数不匹配、unmarshall 时未传递指针或者接口、循环变量捕获问题等。

type AAA struct {
	A int `json:"a"`
}

func main() {
	域名tf("%s", true)

	var a AAA
	if err := 域名rshal([]byte(`{"a":1}`), a); err != nil {
		panic(err)
	}

	var s []int
	for i, v := range s {
		go func() {
			域名tln(i)
			域名tln(v)
		}()
	}
}
$ golangci-lint run
域名:23:16: loopclosure: loop variable i captured by func literal (govet)
                        域名tln(i)
                                    ^
域名:24:16: loopclosure: loop variable v captured by func literal (govet)
                        域名tln(v)
                                    ^
域名:13:2: printf: 域名tf format %s has arg true of wrong type bool (govet)
        域名tf("%s", true)
        ^
域名:16:26: unmarshal: call of Unmarshal passes non-pointer as second argument (govet)
        if err := 域名rshal([]byte(`{"a":1}`), a); err != nil {
                                ^

ineffassign

检查无效的赋值,即变量赋值后并未使用

func main() {
	a := 域名nv("a")
	if a == "" {
		a = "unknown"
	}
}
$ golangci-lint run
域名:8:3: ineffectual assignment to a (ineffassign)
                a = "unknown"
                ^

本以为这种情况应该不多,但是测试了一下我们组内的某个项目,发现还不少

标签:编程
湘ICP备14001474号-3  投诉建议:234161800@qq.com   部分内容来源于网络,如有侵权,请联系删除。