1. 程式人生 > >golang _下劃線占位符代替需要釋放的資源的問題

golang _下劃線占位符代替需要釋放的資源的問題

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("
GET", "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) // 保持進程一直運行,當進程停止時會被操作系統強行回收資源 }
View Code

抓包結果:

技術分享圖片

可以看到請求結束之後30秒依然沒有發送FIN包來斷開連接。這個時候我手動Ctrl+C終止進程後:

技術分享圖片

正常進行了四次揮手。打開了文件都要關閉大家都知道,但是這裏特殊的地方在於golang中使用_下劃線並不是靠譜的。

golang _下劃線占位符代替需要釋放的資源的問題