主要观点:
- “不要恐慌”(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()
确保排序列只包含安全字符。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。