在 Go 中何时可以恐慌? - Alex Edwards

主要观点:

  • “不要恐慌”(don't panic)是 Go 语言中的一个谚语,意为优雅地处理错误或返回给调用者处理,而非使用内置的panic()函数,但panic()函数并非绝对不能用,它是一个工具,在某些罕见情况下是合适的。
  • 正常情况下应返回错误让调用者控制如何处理,这样更灵活且符合 Go 语言的习惯,同时返回错误还有一些好处,如可包装错误提供额外上下文、便于写单元测试、对其他使用者更礼貌等。
  • 可将错误分为“操作错误”(operational errors)和“程序员错误”(programmer errors),操作错误应返回给调用者处理,程序员错误在某些情况下可以使用panic(),如错误不可恢复、返回错误会增加过多复杂度、作为最后一道“防护条款”防止不应发生的操作或程序无法继续且无更好处理方式时。

关键信息:

  • panic()函数在 Go 代码中会立即停止当前函数的正常执行,逆序运行当前 goroutine 的延迟函数,打印panic:和传递的错误值到os.Stderr并输出当前 goroutine 的堆栈跟踪,以退出码 2 终止程序。
  • 操作错误是程序运行中可能合理预期发生的错误,应返回给调用者处理;程序员错误是由开发者错误、代码逻辑缺陷等导致的错误,在某些情况下可使用panic()
  • 给出了一些 Go 标准库中触发panic()的场景,如除以 0、访问越界、解引用空指针等。
  • 列举了几个实际代码中的panic()使用示例,如从 HTTP 请求上下文中获取用户值、从环境变量转换为整数、在 SQL 排序条件中进行安全检查等。

重要细节:

  • timeIn()函数中,正常处理错误是返回错误,若使用panic()则会触发panic行为。
  • contextGetUser()函数中,因在特定应用中逻辑上期望请求上下文中有用户值,缺失值被视为程序员错误,使用panic()更合适。
  • getEnvInt()函数中,在程序启动早期读取环境变量并转换为整数时,由于未初始化日志且无其他好的错误处理方式,使用panic()合理。
  • OrderBySQL()方法中,作为防止 SQL 注入的最后一道防护条款,使用panic()确保排序列只包含安全字符。
阅读 7
0 条评论