golang _下劃線占位符代替需要釋放的資源的問題
阿新 • • 發佈:2017-12-21
color lap ngs pla open pan mage 操作 read
golang中_有兩種作用,一種用在import中,比如這樣
import _ "github.com/go-sql-driver/mysql"
表示並不需要導入整個包,只是執行這個包裏面所有的init函數。另一個作用就是作為變量的占位符,比如req, _ := http.NewRequest(....),這裏http.NewRequest返回的是兩個參數,但是如果我並不需要用到error參數時,就可以用_線代替。
但是這裏就有一種特殊情況了,例如,response, err := Client.Do(req),這種場景還是比較常見的,就是發起一個http請求時,當我不關心response時,是否可以用_代替而不接收這個參數呢?
答案是不可以的。因為這裏發起http請求時,已經打開了一個tcp連接,如果不顯式的調用 response.Body.Close()的話,是不會自動斷開tcp連接的,盡管golang的gc已經完成了內存的回收,但是仍然不會關閉tcp連接。下面測試過程:這裏測試請求了baidu,然後用_代替response參數,用tcpdump進行抓包
代碼如下:
package main import ( log "ad-service/alog" "net/http" "strings" "time" ) func send() { req, err := http.NewRequest("View CodeGET", "http://baidu.com", strings.NewReader("")) if err != nil { log.Error(err) return } client := http.Client{} _, err := client.Do(req) //resp, err := client.Do(req) // 不調用Close if err != nil { log.Error(err) return } //defer resp.Body.Close()// 不調用Close } func main() { send() time.Sleep(1000 * time.Second) // 保持進程一直運行,當進程停止時會被操作系統強行回收資源 }
抓包結果:
可以看到請求結束之後30秒依然沒有發送FIN包來斷開連接。這個時候我手動Ctrl+C終止進程後:
正常進行了四次揮手。打開了文件都要關閉大家都知道,但是這裏特殊的地方在於golang中使用_下劃線並不是靠譜的。
golang _下劃線占位符代替需要釋放的資源的問題