将恐慌/恢复视为throw/catch是错误的

pm1*_*100 6 go

作为一个新的发烧友,尝试使用错误处理的方式.要清楚 - 我喜欢例外.

我有一个服务器接受连接,处理一组请求并回复它们.我发现我能做到

if err != nil{
      panic(err)
}
Run Code Online (Sandbox Code Playgroud)

在深入处理代码中

并有

defer func() {
        if err := recover(); err != nil {
            log.Printf("%s: %s", err, debug.Stack()) // line 20
        }
    }()
Run Code Online (Sandbox Code Playgroud)

在客户端连接代码中(每个连接都在goroutine中).这很好地包装了一切,强行关闭连接(其他延迟消防),我的服务器继续嗡嗡声.

但这感觉非常像投掷/捕获场景 - golang说它不支持.问题

  • 这是稳定的吗?即恢复恐慌是一件好事,可以作为一种持续的生活方式.它不打算只是稍微推迟立即关机
  • 我寻找关于这个主题的讨论,并没有在任何地方找到它 - 任何指针?

我觉得答案是'是的有效'并且可以在你自己的代码中使用,但恐慌不应该被更广泛使用的库使用.库的标准和礼貌方式是错误返回

ANi*_*sus 10

是的,你可以做你的建议.在标准软件包中有一些情况下使用panic/recover来处理错误.在官方博客转到状态:

有关恐慌恢复的真实示例,请参阅Go标准库中的json包.它使用一组递归函数对JSON编码的数据进行解码.当遇到格式错误的JSON时,解析器调用panic将堆栈展开到顶级函数调用,该函数调用从恐慌中恢复并返回适当的错误值(请参阅解码中的decodeState类型的'error'和'unmarshal'方法) .走).

一些指示:

  • 使用error您的正常使用情况.这应该是您的默认值.
  • 如果使用panic/ recover(例如使用递归调用堆栈)使代码变得更清晰和简单,则将其用于该特定情况.
  • 永远不要让包裹泄漏恐慌.包中使用的恐慌应该在包中恢复并作为错误返回.
  • 从恐慌中恢复是稳定的.不要担心恢复后继续执行.您可以在标准库中看到此类行为,例如使用net/http从处理程序中的panic中恢复的程序包,以防止整个http服务器在单个请求上进行混乱时崩溃.