高质量代码与编码规范 | 青训营

73 阅读4分钟

高质量代码

通用的原则:简单性,可读性,生产力,以及下面强调的正确问题,考虑到多种情况

  1. 各种边界条件是否考虑完备
  2. 异常情况处理,稳定性保证
  3. 易读易维护

编码规范

开源的编码规范文档,比较重要的下面几点

  1. 注释:公共符号(变量,常量,函数,结构体)始终要注释,库中公开提供的所有函数都必须注释。有一个例外,不需要注释实现接口的方法

    注释应当解释代码的功能,如何实现(尤其是一些看起来有点复杂的逻辑),实现的原因(适合解释代码的外部因素,比如说各种接口的问题状态码之类,提供额外上下文),什么情况下会出错(解释代码的限制条件)

    原则:代码是最好的注释,注释应该提供代码未表达出的上下文信息

  2. 代码格式:这是一个基础,团队的编码格式要统一,gofmt / goimports(gofmt + 依赖包管理,分类字母排序) 官方内置功能

  3. 命名规范:简洁胜于冗长,最好一眼就能知道啥意思

  • 变量命名的规则:缩略词如 HTTP 全大写,但当其位于变量开头且不需要导出时,全小写。具体命名的时候,变量距离它被使用的地方越远,就越要把名称写详细。还有全局变量,这是最要写详细的。有时候也要写短,比如说循环中的 i tmp,它们的作用域小嘛,但比如说如果函数要提供给外部调用,参数就不能写这种 t 啊 i 啊之类的,写明白到底啥意思
  • 函数命名的规则:函数名不携带包名的上下文信息,因为包名和函数名总是成对出现的,也由于这个原因,如果返回的类型名和包名差不多,那么可以省略类型信息,但如果返回的是其他类型,可以在函数名中加入返回值类型信息
       //举例
       package time
       func Now() Time        //调用时 time.Now, 更简洁也清楚
       func NowTime() Time    //调用时 time.NowTime
       ```
    
  • 包命名的规则:只有小写字母,不要与标准库同名。尽量满足,不使用常见常量名作为报名,使用单数少用复数,谨慎用英文缩写,得大家公认的才行
  1. 控制流程:条件和循环

    • 避免 if-else 嵌套
    • 尽量让缩进最小化。比如说优先处理错误情况和特殊情况,尽早返回或继续循环来减少嵌套
    • 控制流程最好走直线,沿屏幕向下移动
  2. 错误和异常处理:error 尽可能提供简明上下文信息链,真正救不回来的 panic,在外部 panic 需要 recover 的时候请

    • 简单错误:仅出现一次,其他地方不需要它,返回错误信息就行。这时候,如果简单描述一下就 errors.New("错误提示"),如果有格式化的需求就 fmt.Errorf(这两个的输出是什么样的?查一下)
    • 复杂错误:Wrap Unwrap 嵌套错误,生成错误生成链,每一层都能提供出错的上下文信息。在 fmt.Errorf 中使用 %w 关键字可以将一个错误关联至错误链中
    • panic:程序崩溃,最好不要在业务代码中使用,如果问题可以屏蔽或解决,可以用 error 代替 panic。但如果程序启动阶段就遇到了不可逆转的错误,尽早暴露错误,就直接打出日志,panic
    • recover:处理 panic 崩溃,方便我们处理外部调用的代码 panic 了的情况。使用规则是 recover 只能在 defer 中生效,只能在当前协程中生效,无法嵌套。在写 defer 时,请注意 defer 语句是先进后出的,以此判断到底哪里的 defer 先调用
    • 如果需要更多的上下文信息,可以 recover 后在 log 中记录当前调用栈
      //判定错误链中是否含有特定错误
      errors.Is(err, fs.ErrNotExist)
      //在错误链上获取特定种类的错误
      var pathError *fs.PathError
      errors.As(err, &pathError)
      fmt.Println ... pathError.Path  //打印这个种类的错误的内容
    
      //recover
      defer func() {
          if e:= recover(); e != nil {
              f = nil
              err = fmt.Errorf("gitfs panic: %v\n%s", e, debug.Stack())
          }()
      }
      ```
    

学生阶段特别容易忽视这种编码规范,但这些规范又是很重要的,需要多在实践中加以运用呀