在下面的代碼是它也需要關閉響應主體在錯誤情況下:如果在調用http.Get(url)時發生錯誤,我們是否需要關閉響應對象?
res, err := http.Get(url)
if err != nil {
log.Printf("Error: %s\n", err)
}
defer res.Body.Close()
在下面的代碼是它也需要關閉響應主體在錯誤情況下:如果在調用http.Get(url)時發生錯誤,我們是否需要關閉響應對象?
res, err := http.Get(url)
if err != nil {
log.Printf("Error: %s\n", err)
}
defer res.Body.Close()
一般概念是,當一個函數(或方法)具有多返回值一個是error
,誤差應首先檢查,如果錯誤是nil
,則僅執行。如果存在error
,函數應該爲其他(非錯誤)值返回零值。如果函數的行爲不同,它應該被記錄下來。 http.Get()
沒有記錄這種偏差。
所以應該這樣處理:
res, err := http.Get(url)
if err != nil {
log.Printf("Error: %s\n", err)
return
}
defer res.Body.Close()
// Read/work with body
注:
由於JimB確認過,如果返回了非nil
錯誤,即使響應是非 - nil
,我們不必關閉它。如果發生重定向錯誤,則非響應可能包含上下文以及關於重定向失敗後的位置的更多信息。詳情請見下文:
http.Get()
榮譽的一般概念「大部分時間」:返回nil
響應,如果有一個錯誤:
return nil, someError
但是檢查client.go
,未導出的方法Client.doFollowingRedirects()
,目前線#427:
if redirectFailed {
// Special case for Go 1 compatibility: return both the response
// and an error if the CheckRedirect function failed.
// See https://golang.org/issue/3795
return resp, urlErr
}
所以由於向後兼容性問題,它可能會返回在同一時間非0響應和非nil
錯誤,我f重定向失敗。如果resp
是nil
將導致運行時恐慌。
因此,如果我們要關閉響應主體在這種情況下,它可能是這樣的(只能暫時封閉resp
不nil
):
res, err := http.Get(url)
if err != nil {
log.Printf("Error: %s\n", err)
}
if res != nil {
defer res.Body.Close()
// Read/work with body
}
或者:
res, err := http.Get(url)
if err != nil {
log.Printf("Error: %s\n", err)
}
if res == nil {
return
}
defer res.Body.Close()
// Read/work with body
的doc http.Response
保證即使沒有響應數據,Response.Body
也不會是nil
:
// The http Client and Transport guarantee that Body is always
// non-nil, even on responses without a body or responses with
// a zero-length body.
如果您得到一個需要關閉錯誤的響應主體,那是需要提交的錯誤。在這種情況下,您應該爲身體設置一個空的靠近,這樣只會使關閉不會驚慌。 – JimB
@JimB這就是我的想法。感謝您的確認。將編輯答案。 – icza
我去了,並且雙重檢查了客戶端代碼,並且在重定向錯誤返回Response的情況下,Body已經關閉,並且連接被釋放。雖然它並沒有受到傷害,但在客戶端出錯後,永遠不需要'推遲resp.Body.Close()'。 – JimB