annidy / notes

0 stars 0 forks source link

编码规范 #327

Open annidy opened 1 week ago

annidy commented 1 week ago

Uber Go 语言编码规范

go语言强制统一对齐方式,编码规范更多侧重代码使用层面。

节选

错误类型

Go 中有多种声明错误(Error) 的选项:

返回错误时,请考虑以下因素以确定最佳选择:

  1. 这是一个不需要额外信息的简单错误吗?如果是这样,errors.New 足够了。
  2. 客户需要检测并处理此错误吗?如果是这样,则应使用自定义类型并实现该 Error() 方法。
  3. 您是否正在传播下游函数返回的错误?如果是这样,请查看本文后面有关错误包装 section on error wrapping 部分的内容。
  4. 否则 fmt.Errorf 就可以了。

如果客户端需要检测错误,并且您已使用创建了一个简单的错误 errors.New,请使用一个错误变量。 如果您有可能需要客户端检测的错误,并且想向其中添加更多信息(例如,它不是静态字符串),则应使用自定义类型。

错误包装 (Error Wrapping)

一个(函数/方法)调用失败时,有三种主要的错误传播方式:

  1. 如果没有要添加的其他上下文,并且您想要维护原始错误类型,则返回原始错误。
  2. 添加上下文,使用 "pkg/errors".Wrap 以便错误消息提供更多上下文 ,"pkg/errors".Cause 可用于提取原始错误。
  3. 使用 fmt.Errorf ,如果调用者不需要检测或处理的特定错误情况。 specific error case. 建议在可能的地方添加上下文,以使您获得诸如“调用服务 foo:连接被拒绝”之类的更有用的错误,而不是诸如“连接被拒绝”之类的模糊错误。

在将上下文添加到返回的错误时,请避免使用“failed to”之类的短语来保持上下文简洁,这些短语会陈述明显的内容,并随着错误在堆栈中的渗透而逐渐堆积:

在边界处拷贝 Slices 和 Maps

slices 和 maps 包含了指向底层数据的指针,因此在需要复制它们时要特别注意。

Channel 的 size 要么是 1,要么是无缓冲的

channel 通常 size 应为 1 或是无缓冲的。默认情况下,channel 是无缓冲的,其 size 为零。任何其他尺寸都必须经过严格的审查。考虑如何确定大小,是什么阻止了 channel 在负载下被填满并阻止写入,以及发生这种情况时发生了什么。

优先使用 strconv 而不是 fmt

将原语转换为字符串或从字符串转换时,strconv速度比fmt快。

nil 是一个有效的 slice

nil 是一个有效的长度为 0 的 slice,这意味着,

  1. 您不应明确返回长度为零的切片。应该返回nil 来代替。
  2. 要检查切片是否为空,请始终使用len(s) == 0。而非 nil。
  3. 零值切片(用var声明的切片)可立即使用,无需调用make()创建。

函数分组与顺序

函数应按粗略的调用顺序排序。 同一文件中的函数应按接收者分组。 因此,导出的函数应先出现在文件中,放在struct, const, var定义的后面。

在定义类型之后,但在接收者的其余方法之前,可能会出现一个 newXYZ()/NewXYZ()

由于函数是按接收者分组的,因此普通工具函数应在文件末尾出现。

对于未导出的顶层常量和变量,使用_作为前缀

在未导出的顶级vars和consts, 前面加上前缀_,以使它们在使用时明确表示它们是全局符号。

不要 panic

在生产环境中运行的代码必须避免出现 panic。panic 是 cascading failures 级联失败的主要根源 。如果发生错误,该函数必须返回错误,并允许调用方决定如何处理它。

panic/recover 不是错误处理策略。仅当发生不可恢复的事情(例如:nil 引用)时,程序才必须 panic。程序初始化是一个例外:程序启动时应使程序中止的不良情况可能会引起 panic。

var _statusTemplate = template.Must(template.New("name").Parse("_statusHTML"))