You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言中'*'与'&'符号的含义及函数返回指针类型的原因

为什么Go中有些函数会返回指针类型(比如net/http.NewRequest)

我当初刚学Go的时候也对这个点纠结过,既然你已经懂了指针接收器能修改指向的值,那咱们就顺着这个思路,拆解下函数返回指针的核心原因:


1. 避免大对象拷贝带来的性能损耗

像http.Request这种结构体,内部包含了Header、Body、URL、Cancel等一大堆字段,要是函数返回值类型,每次调用都会完整拷贝整个结构体到调用栈里——这对于频繁创建请求的场景来说,是不小的性能浪费。而返回指针的话,只需要拷贝一个8字节(64位系统)的内存地址,成本低得多。

2. 允许调用者修改返回的对象

你想想,创建完请求后,咱们通常要做什么?加请求头、设置超时、修改URL参数对吧?如果NewRequest返回的是值类型,那你修改的只是拷贝后的副本,原对象根本没变化——这就意味着你做的这些修改完全无效,发送请求的时候还是用的最初的默认值。

比如这段代码如果返回值类型就会出问题:

req, err := http.NewRequest("GET", "https://example.com", nil)
if err != nil {
    // 处理错误
}
req.Header.Add("Authorization", "Bearer my-token") // 这里修改的是副本,原请求对象没变化

但返回指针的话,你操作的就是NewRequest内部创建的那个真实对象,修改会直接生效,符合咱们的预期。

3. 用nil表示“无效/不存在”的状态

Go里值类型的结构体没法直接表示“空”的状态——哪怕你初始化一个零值结构体,它也还是一个合法的对象。但指针可以返回nil,用来明确表示函数创建对象失败的情况。比如NewRequest如果解析URL失败,就会返回nil和对应的error,调用者一眼就能判断请求对象是否有效:

req, err := http.NewRequest(...)
if err != nil || req == nil {
    // 处理创建失败的情况
}

4. 符合Go的惯用设计风格

在Go的标准库中,对于复杂、可变的结构体,几乎都会用指针来传递和返回。这样做能保持代码的一致性:你拿到指针后,后续调用其他相关函数(比如client.Do(req))时,不需要额外做值转指针的操作,代码更简洁流畅。


总结一下,返回指针本质上是为了性能优化、支持修改、明确空状态这几个核心需求,而net/http.NewRequest刚好同时满足这些场景~

内容的提问来源于stack exchange,提问作者user2989731

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:09:28