go语言代码规范.md 4.0 KB

2021

go语言编码规范

建信金科 智能云事业部 产品创新和云技术团队

2021-01-25

  • 格式化

    • 使用gofmt格式化
    • 一行最好不要超过120个字符
  • 使用golint进行go代码的检测

  • 使用go vet静态分析代码问题

  • log

    • 使用第三方库 https://github.com/sirupsen/logrus

    • log定向到标准输出 SetOutput(os.Stdout)

    •     
      import (
      log "github.com/sirupsen/logrus"
      "os"
      )
          
      func init() {
      log.SetFormatter(&log.JSONFormatter{})//设置日志的输出格式为json格式,还可以设置为text格式
      log.SetOutput(os.Stdout)//设置日志的输出为标准输出
      log.SetLevel(log.InfoLevel)//设置日志的显示级别,这一级别以及更高级别的日志信息将会输出
      }
      
  • GOPATH

    • 单一的 GOPATH原则,除非你的项目很大并且极为重要,否则不要为每个项目使用不同的 GOPAHT
  • 文件命名,目录名(包名)

    • 使用小写
    • 不同单词之间用下划线分词,不要使用驼峰式命名
    • 如果是测试文件,以 _test.go结尾
    • 保持package的名字和目录保持一致
    • 不要和标准库冲突
    • 一个目录只实现一个包
  • 常量命名

    • 使用全大写且用下划线分词,比如 APP_VERSION

    • 如果要定义多个变量,请使用 括号 来组织

    •    
      const (
      APP_VERSION = "0.1.0"
      CONF_PATH = "/etc/xx.conf"
      )
      
  • 变量命名

    • 统一使用 驼峰命名法
    • 一般情况下首单词全小写,其后各单词首字母大写
    • 首单词小写(变量为私有)
    • (变量不是私有),那首单词就要变成全大写
    • 局部变量可以使用简单变量名
  • 函数命名

    • 驼峰命名法
    • 不需要在包外访问,请使用小写字母开头
    • 需要在包外访问,请使用 大写字母开头
  • 接口命名

    • 使用驼峰命名法
    • 大写开头的 type 给包外访问
  • 注释

    • 包注释,位于 package 之前,如果一个包有多个文件,只需要在一个文件中编写即可
    • 如果是特别复杂的包,可单独创建 doc.go 文件说明
    • 包、函数、方法和类型的注释说明都是一个完整的句子
    • 特别注释
    • TODO:提醒维护人员此部分代码待完成
    • FIXME:提醒维护人员此处有BUG待修复
    • NOTE:维护人员要关注的一些问题说明
  • context

    • 不要把context 放入结构体中
    • 函数中使用context 类型做为参数时 应该做为第一个参数
    • context 在函数中传递的过程中是不可以改变的
  • goroutine

    • 完成任务的goroutine 确保退出
    • 尽可能少使用channel
  • 函数返回值

    • 直接使用类型返回值,避免使用返回命名参数
  • copy

    • 使用时要小心指针
  • 传值

    • 对于大型的数据结构,或者小型的可能增长的结构,考虑使用指针
  • 包导入

    • 多个包导入,请使用 {} 来组织

    •    
      import {
      "fmt"
      "os"
      }
      
    • 标准库排最前面,第三方包次之、项目内的其它包和当前包的子包排最后,每种分类以一空行分隔

    • 不要使用相对路径来导入包

  • 错误处理

    • 不能丢弃任何有返回error的调用,不要采用_丢弃,必须全部处理
  • if

    • 尽量不要在if 语句中初始化 语句,而应该另起一行
  • 闭包

    • 在循环中调用函数或者goroutine方法,一定要采用显示的变量调用,不要再闭包函数里面调用循环的参数

    •    
      for i:=0;i<limit;i++{
      go func(){ DoSomething(i) }() //错误的做法
      go func(i int){ DoSomething(i) }(i)//正确的做法
      }
      
  • recieved是值类型还是指针类型

    •       
      func(w Win) Tally(playerPlayer)int    //w不会有任何改变 
      func(w *Win) Tally(playerPlayer)int    //w会改变数据
      
    • 如果定义的struct中带有mutex,那么你的receivers必须是指针