「笔记003」Go高质量编程

2024 年 11 月 23 日 星期六(已编辑)
7
摘要
这段文字描述了一个Go语言编程的代码规范指南,以确保代码正确可靠、简洁清晰、涵盖边界条件并具备良好的异常处理能力。详细规定了代码格式化(使用gofmt和goimports)、注释规范(功能、细节、原因解释)、命名规范(变量、函数、包的命名方式),以及流程控制与错误处理的方法。鼓励减少代码嵌套,使用清晰的逻辑结构,适当应用defer机制。在错误处理方面,强调错误的简单化处理、错误链的构建与判断,避免使用panic,重视错误的恢复和程序的健壮性。该规范贯彻了减少冗余和复杂性的核心原则,旨在使代码更易于阅读和维护。
这篇文章上次修改于 2024 年 11 月 23 日 星期六,可能部分内容已经不适用,如有疑问可询问作者。

「笔记003」Go高质量编程

核心要求

  1. 正确可靠:代码功能实现准确、逻辑严密。
  2. 简介清晰:代码结构与实现尽可能简洁,逻辑直观。
  3. 边界条件完备:考虑所有可能的输入及场景,保证功能覆盖边界情况。
  4. 异常处理:通过有效的异常处理机制,提升代码稳定性。
  5. 可读性与可维护性:代码应清晰易懂,便于他人理解和修改。

代码规范细则

1. 代码格式化

  • gofmt: 统一代码风格,符合Go官方规范。
  • goimports: 在gofmt基础上自动管理依赖包。

2. 注释规范

  • 注释功能
    • 解释代码的作用:注释要描述代码的目的和作用。
    • 解释实现细节:解释代码的逻辑或设计背后的思路。
    • 阐明原因:说明为何采取当前实现方式。
    • 指出潜在错误:记录代码运行时可能遇到的问题。
  • 注释范围
    • 公共符号(变量、常量、函数、结构体)。
    • 复杂、难懂的逻辑,无论公私范围。
    • 库函数中任何公共功能(实现接口的方法除外)。

3. 命名规范

  • 变量命名
    • 简洁明了,避免冗长。
    • 缩略词全大写(如HTTP),私有变量首字母小写。
    • 距离使用越远,名称应提供更多上下文信息。
  • 函数命名
    • 避免重复包名信息。
    • 如果返回的对象类型明显,可省略类型信息。
  • 包命名
    • 小写字母,无下划线、无大写。
    • 避免与标准库冲突(如bufio)。
    • 使用单数形式(如encoding)。
    • 避免缩写,除非广泛认可(如fmt)。
  • 核心原则
    • 减少认知负担。
    • 增强代码上下文表达力。

4. 流程控制

  • 减少嵌套
    • if-return优化if-else结构。
    • 尽早处理异常/特殊情况,减少后续逻辑复杂度。
  • 直线逻辑
    • 避免冗长嵌套。
    • 按屏幕自上而下编排逻辑,便于阅读。

5. 错误和异常处理

  • 简单错误
    • 不复用的简单错误,直接用errors.Newfmt.Errorf
  • 错误包装与解包
    • fmt.Errorf%w关键字构建错误链。
    • errors.Is判断特定错误。
    • errors.As提取特定类型错误。
  • panicrecover
    • panic:不建议在业务代码中使用,适用于程序初始化阶段的不可逆错误。
    • recover:只能在defer函数中使用,适用于捕获panic并恢复程序运行。

6. defer 使用注意事项

  • defer 语句在函数返回前执行。
  • 多个defer语句后进先出(栈行为)。
  • 在分支中使用defer时,所有分支的defer按调用顺序压栈。

示例与扩展

1. 简单错误处理

if err != nil {
    return fmt.Errorf("failed to read file: %w", err)
}

2. 错误链与判断

var pathError *fs.PathError
if errors.As(err, &pathError) {
    fmt.Println("Specific error type detected:", pathError.Path)
}
if errors.Is(err, os.ErrNotExist) {
    fmt.Println("File does not exist")
}

3. defer 的行为

func exampleDefer() {
    defer fmt.Println("Executed last")
    defer fmt.Println("Executed second")
    fmt.Println("Executed first")
    // Output:
    // Executed first
    // Executed second
    // Executed last
}

注意

  • 遵循最小必要原则,减少代码冗余。
  • 优先使用Go语言的内置特性,如defererror机制。
  • 通过注释和清晰命名,提升代码的表达能力,降低沟通成本。

使用社交账号登录

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...