Golang函数或方法传递nil值的一个坑

Copy Highlighter-hljs
package t13_niu_error import ( "bytes" "fmt" "io/ioutil" "net/http" "testing" ) // 将请求获取的数据转为string,支持GET或POST请求 func BaseRequestString(requestMethod, url string, requestBody *bytes.Reader) (string, error) { client := &http.Client{ } var req *http.Request var err error // 特别注意这里,即使外边requestBody传nil的话 // 但是它的类型type是 *bytes.Reader,传给http.NewRequest方法的最后一个参数不是需要的io.Reader类型的!会报错 req, err = http.NewRequest(requestMethod, url, requestBody) if err != nil { return "", err } res, err := client.Do(req) if err != nil { return "", err } defer res.Body.Close() body, err := ioutil.ReadAll(res.Body) if err != nil { return "", err } return string(body), nil } // 测试 func TestNilError(t *testing.T) { // GET if res, err := BaseRequestString("GET", "https://www.baidu.com", nil); err != nil { fmt.Println("err>> ", err.Error()) } else { fmt.Println("res>> ", res) } }

如果按照这种实现的方式,程序会上报一个错误:

Copy Highlighter-hljs
panic: runtime error: invalid memory address or nil pointer dereference [recovered]

其实错误就出在了nil的类型不一样。

我们可以看到,在函数定义阶段,requestBody定义的是bytes.Reader类型的,也就是说外部传入的nil也是bytes.Reader类型的。

但是我们再在http.NewRequest方法中看一下它的源码:

Copy Highlighter-hljs
// NewRequest wraps NewRequestWithContext using the background context. func NewRequest(method, url string, body io.Reader) (*Request, error) { return NewRequestWithContext(context.Background(), method, url, body) }

在Go语言中,变量总是被一个定义明确的值初始化,即使接口类型也不例外。对于一个接口的零值就是它的类型和值的部分都是nil:

这就很明白了:两个nil值的value虽然都是nil,但是它们的type不同!所以将bytes.Reader类型的nil传入需要io.Reader类型的nil参数的位置,肯定会报错的!
解决:
requestBody改为接口类型 requestBody interface{}就可以了

posted @   caibaotimes  阅读(53)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
历史上的今天:
2020-09-22 MySQL5.7优化InnoDB配置以及调优方案
2020-09-22 mysql实现分组查询每个班级的前三名
2020-09-22 PHP脚本执行超时的解决办法
2020-09-22 php中proc_open函数
2020-09-22 MySql版本问题sql_mode=only_full_group_by的完美解决方案
2020-09-22 PHP常用函数
2020-09-22 基础
点击右上角即可分享
微信分享提示