golang代码规范[翻译+自嗨]

gofmt

  • 务必执行gofmt 强制格式化自己的代码
  • 使用goimports 自动带入需要的包或者删除不需要的包

ps:goland 支持file watcing tools 可以添加gofmt 或者 goimports 这样开发过程中就会自动执行


注释

  • 注释一定要是完整的句子,这样有利于提取到godoc 文档中
  • 注释应该以描述功能的名称开头 比如:
  • 包注释及时有多个文件也只要在一个文件写就好
// Request represents a request to run a command.
type Request struct { ...

// Encode writes the JSON encoding of req to w.
func Encode(w io.Writer, req *Request) { ...

  • 除了句号之外,还有其他符号可以作为句子的有效结尾(比如!,?)

context

  • 不要把context 放入结构体中

  • 函数中使用context 类型做为参数时 应该做为第一个参数

func F(ctx context.Context, /* other arguments */) {}
  • 尽量不要使用nil的context,如果不知道使用哪中类型的context 可以使用context.TODO()
  • 不要在函数签名中创建Context类型或者使用Context以外的接口
  • context 在函数中传递的过程中是不可以改变的

goroutine

  • 使用goroutine 时确保在什么条件退出,因为goutine可能会因为阻塞channel的发送或者接收而泄露,gc 就不会终止goroutine
  • 即使没有泄露,当不再需要他们时却仍在继续运行会导致难以诊断的问题,即使不需要结果,又有可能会导致数据竞争

copy

  • 复制结构时一定要小心 因为这个类型可能包含一个指针类型,在后续的操作中可能会有意向不到的后果
    比如:bytes.Buffer 中包含了[]byte 切片类型

rand

  • 推荐使用crypto/rand 来生成秘钥,而不是math/rand 因为math/rand 不提供随机种子就会重复,即使提供了随机种子也只是几位差别
    比如:
package main

import (
	"crypto/rand"
	"encoding/hex"
	"fmt"
)

func Key() string {
	buf := make([]byte, 8)
	_, err := rand.Read(buf)
	if err != nil {
		panic(err) // out of randomness, should never happen
	}
	return hex.EncodeToString(buf)
	// or return base64.StdEncoding.EncodeToString(buf)
	// or return fmt.Sprintf("%x", buf)

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

空切片

  • 申明一个空切片时使用
var r []string    // nil

而不是

t := []string{} // non-nil

他们的cap 和len 相同但是 nil 切片应该作为首选方案 不过在某些情况下non-nil 的表现更好

panic

  • 总之尽量不要使用panic 来做错误处理机制,使用error

错误处理

  • 错误信息字符串要使用小写字母,除非专业名词
  • 不要使用 _ 来丢弃错误,请尽量检查错误
  • 当返回值表示无效时使用多返回值,如果错误不需要说明 使用false,可以防止调用者错误的使用结果
  • 减少缩进,尽快的处理掉错误信息
  • 尽量不要在if 语句中初始化 语句,而应该另起一行

import

  • 推荐使用 goimports 其他的就不用管了!

名称

  • 如果要在其他包使用请大写开头
  • 名称的首字母如果是小写要注意一些专有的名词不能去改变 如:URL 不是Url ServerHTTP 而不是ServerHttp
  • 变量名尽量短,不过这个看公司的要求与风格,毕竟短也容易重复,想个变量名也不容易
  • 包名应该简洁,清晰 意义深刻,由小写字母组成,不能出现下划线或者大写
  • 避免无意义的包名如 util,common,api,interface
  • 组合名不要使用下划线等来链接单词

传值

  • 不要为了节省几个字节而传指针给函数,如果仅仅是为了把参数x 作为*x 使用那就不应该用指针
  • 常见的传指针的情况有传递一个string 的指针 指向接口值(*io.Reader)的指针
  • 对于大型的数据结构,或者小型的可能增长的结构 考虑使用指针

函数

  • 函数结果参数只有在返回值意义不明确的时候才使用,尽量保证可读性(其实添加注释才是重要的)
  • 入参和出参的命名都用小写的

emmmmm~~ 还挺多的一下想不到了 后面再补吧

你可能感兴趣的:(golang)