GoLang - 将nil传递给接受接口的函数

时间:2016-09-21 01:10:11

标签: go function-parameter go-interface

我最近偶然发现了一些让我在golang中循环的东西。

/>

当nil直接传递给package main import ( "net/http" "bytes" "fmt" "io/ioutil" ) func createRequest(method, uri string, data *bytes.Buffer) string { req, err := http.NewRequest(method, uri, data) if err != nil { return "" } req.Close = true client := &http.Client{} resp, err := client.Do(req) if err != nil { return "" } defer resp.Body.Close() respBody, err := ioutil.ReadAll(resp.Body) if err != nil { return "" } return string(respBody) } func createRequestNoBody(method, uri string) string { req, err := http.NewRequest(method, uri, nil) if err != nil { return "" } req.Close = true client := &http.Client{} resp, err := client.Do(req) if err != nil { return "" } defer resp.Body.Close() respBody, err := ioutil.ReadAll(resp.Body) if err != nil { return "" } return string(respBody) } func main() { data := createRequestNoBody("GET", "http://google.com") if len(data) != 0 { fmt.Println("First Request Ok") } data = createRequest("GET", "https://google.com", nil) if len(data) != 0 { fmt.Println("Second Request OK") } } 时,此代码在createRequestNoBody函数中有效,但在http.NewRequest设置为createRequest时调用*bytes.Buffer会产生混乱在调用函数中。

http库中的NewRequest函数具有以下原型:

nil

func NewRequest(method, urlStr string, body io.Reader) (*Request, error)是一个接口。

我不确定为什么通过变量传递的nil会导致NewRequest中的io.Reader变为非零。

有人可以解释为什么body方法导致恐慌吗? createRequest方法中的data = createRequest("GET", "https://google.com", nil)的nil参数如何变为非零?

1 个答案:

答案 0 :(得分:0)

@JimB的评论是正确的。下面这段代码显示对象的类型确实是(* bytes.Buffer,nil)

package main

import (
    "bytes"
    "fmt"
    "reflect"
    "errors"
    "io"
)
func NewRequest(method, urlStr string, body io.Reader) (error) {
    if body == nil {
       fmt.Println("Body Is Nil")
       return nil
    }
    fmt.Println(reflect.TypeOf(body).Elem())
    return errors.New("NOT NIL")
}

func createRequest(method, uri string, data *bytes.Buffer) string {
    fmt.Println("Type Of data is ", reflect.TypeOf(data).Elem())

    if data == nil {
       fmt.Println("data is nil")
    }
    err := NewRequest(method, uri, data)
    if err != nil {
       return err.Error()
    }
    return "OK"
}

func createRequestNoBody(method, uri string) string {
    err := NewRequest(method, uri, nil)
    if err != nil {
       return err.Error()
    }
    return "OK"
}

func main() {
   data := createRequestNoBody("GET", "http://google.com")
   if len(data) != 0 {
      fmt.Println("First Request Ok")
   }
   data = createRequest("GET", "https://google.com", nil)
   if len(data) != 0 {
      fmt.Println("Second Request Not OK")
   }
}

运行的输出如下:

Body Is Nil
First Request Ok
Type Of data is  bytes.Buffer
data is nil
bytes.Buffer
Second Request Not OK

由于body io.Reader是一个接口而不是指向特定类型的指针,当您传入类型为nil的{​​{1}}指针时,它将是一个非bytes.Buffer接口。