七叶笔记 » golang编程 » Golang中一看就会一做就错的几个问题「2」

Golang中一看就会一做就错的几个问题「2」

在《 》中,我们已经介绍了几个一看就会一做就错的问题,下面我接着介绍另外几个问题。

body参数只能读取一次

使用过gin框架的人都是知道,读取body参数可以使用

ioutil.ReadAll(c. request .Body)

方法。但是有一次我发现,我在中间件里读取了body参数,打印了日志后,再在后续逻辑中使用

ioutil.ReadAll(c.Request.Body)

读取body参数,就读取不到了。后面研究gin的源代码才发现,body参数读取一次后就会被从request里删除,如果想读取多次,必须将读取的内容再写到

c.Request.Body

中去。如下:

这样后续操作才可以使用

ioutil.ReadAll(c.Request.Body)

重复读取。

使用resp.Body.Close()关闭 HTTP 响应体失败

在Golang中,使用 HTTP 标准库发起请求、获取响应时,即使你不从响应中读取任何数据或响应为空,都需要手动关闭响应体。但是有时候你会发现即使调了

resp.Body.Close()

方法,但是HTTP 响应体还是没有关闭,并且还发生了panic。之所以这样,是因为 resp 为nil,这样

resp.Body.Close()

就相当于调用了不存在的方法,因此会panic。

正确的做法应该是先检查 HTTP 响应是否为 nil,如果不为 nil ,才调用

resp.Body.Close()

来关闭响应体,如下:

recover只能恢复当前协程的Panic

在Golang中,捕获异常相对来说比较麻烦。因为它不能像在PHP中那样,只要在最外层使用try…catch就可以捕获所有异常。在Golang中,你需要一层一层的去使用defer…recover方法,而且最重要的是这个方法只能用于恢复所在协程的Panic,跨协程的Panic是无法恢复的。如下:

这段代码最终就无法完整地执行下去,因为其中一个协程必然会发生panic,这样就会导致整个应用挂掉,其它协程也随即跟着停止执行。

相关文章