golang _下划线占位符代替需要释放的资源的问题

Posted 夏笑声

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang _下划线占位符代替需要释放的资源的问题相关的知识,希望对你有一定的参考价值。

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 _下划线占位符代替需要释放的资源的问题的主要内容,如果未能解决你的问题,请参考以下文章

mysql精准模糊查询使用CONCAT加占位符(下划线“_”)的使用,直接限定了长度和格式

golang 新人求助 关于格式占位符的问题

golang fmt格式“占位符”

golang fmt格式“占位符”

与 golang 驱动程序一起使用的雪花占位符格式

golang中fmt的'占位符'使用