本文记录了下自己之前在做项目的时候遇到的函数或方法传递nil值的一个坑,后面会附上说明与解决方案。

错误示范

下面这个BaseRequestString函数主要实现的功能是:分别处理GET或POST请求,requestBody参数在GET请求时传nil,POST请求如果请求体里有数据的话需要处理一下请求体的数据传入。

下面是一个错误的示范:

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

原因分析

问题解释

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

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

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

即使传nil的话,源码里面body也是需要 io.Reader类型的nil!

出处

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

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

参考资料

解决方案

既然知道了原因,那么其实我们有2种解决方案:一种是判断一下传入的requestBody值,针对不同的值传入不同的参数,另外一个就是直接将最后一个参数的类型改成io.Reader。

我个人倾向与前者,虽然第一种解决方案看起来麻烦一点,但是实际上更加灵活,因为我们在构建POST请求参数的时候,往往会将结果做成*bytes.Reader类型的:

这里是我自己封装的一个生成POST请求体参数的例子:

所以,构建的请求体数据是*bytes.Reader类型的,没有必要非得跟http.NewRequest保持一致!

所以我自己的解决方案如下:

~~~