ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-01-29 13:33:54  阅读:234  来源: 互联网

标签:err fmt 高质量 go 写出 func Go main 代码


微信图片_20210216141958

前言

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

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

linters

deadcode

检查未使用的代码

var a = 100

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

类似的工具还有 structcheckvarcheck

errcheck

检查未处理的错误

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

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

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

	var i interface{} = 1
	ii := i.(int)
	fmt.Println(ii)

	num, _ := strconv.Atoi("110")
	fmt.Println(num)
}

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

gosimple

简化代码

func main() {
	t := time.Now()
	fmt.Println(time.Now().Sub(t))
}
$ golangci-lint run
main.go:10:14: S1012: should use `time.Since` instead of `time.Now().Sub` (gosimple)
        fmt.Println(time.Now().Sub(t))
                    ^

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

govet

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

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

func main() {
	fmt.Printf("%s", true)

	var a AAA
	if err := json.Unmarshal([]byte(`{"a":1}`), a); err != nil {
		panic(err)
	}

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

ineffassign

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

func main() {
	a := os.Getenv("a")
	if a == "" {
		a = "unknown"
	}
}
$ golangci-lint run
main.go:8:3: ineffectual assignment to a (ineffassign)
                a = "unknown"
                ^

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

标签:err,fmt,高质量,go,写出,func,Go,main,代码
来源: https://www.cnblogs.com/yahuian/p/golangci-lint.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有