how to golang check a variable is nil

go
22,486

Solution 1

A go interface consists of a type and a value. An interface is only nil if both the type and the value are nil. You provided a type but no value: Therefore NewRequest tried to call Read on a nil struct (the value of the interface).

Solution 2

content is nil by default, don't need to assign it

also, you are ignoring the error returned from NewRequest, don't do that. It is telling you why it can't generate a request.

Normal error handling would be something like:

req, err := http.NewRequest("GET", "http://www.github.com", content)
if err != nil {
  // log or complain... req is nil here
} else {
  // do something with req
}

all that said if you really just want to know if req is nil, do:

if req == nil { 
 // handle nil req
} else {
 // use req
}

but as mentioned before, it's much better to handle the error. if err not nil, then you basically can't trust req to be anything valid.

Solution 3

It is a classic trap of the golang language.

To check if it is a real Nil:

p == nil || reflect.ValueOf(p).IsNil()

Reference: https://www.mangatmodi.com/posts/go-check-nil-interface-the-right-way/

Share:
22,486

Related videos on Youtube

sundq
Author by

sundq

linux c nodejs python developer

Updated on April 12, 2021

Comments

  • sundq
    sundq over 2 years

    my code is like this, when I use req, _ := http.NewRequest("GET", "http://www.github.com", content), it will emit exception:

    panic: runtime error: invalid memory address or nil pointer dereference
    [signal 0xb code=0xffffffff addr=0x0 pc=0xaab78]
    
    goroutine 1 [running]:
    net/http.NewRequest(0x34f3b8, 0x3, 0x378020, 0x15, 0xfeec4350, 0x0, 0x10738801, 0x0, 0x0, 0x107000e0)
        /usr/local/go/src/net/http/request.go:570 +0x498
    main.main()
        /tmp/sandbox056954284/main.go:17 +0xe0
    

    but when I use req, _ := http.NewRequest("GET", "http://www.github.com", nil), it works, why? how I set the third argument value

    package main
    
    import (
        "bytes"
        "net/http"
    )
    
    
    func main() {
        client := &http.Client{}
        var content *bytes.Reader
        content = nil
        req, _ := http.NewRequest("GET", "http://www.github.com", content)
        resp, _ := client.Do(req)
        defer resp.Body.Close()
    }
    
  • sundq
    sundq about 8 years
    But why content == nil return true
  • 0x434D53
    0x434D53 about 8 years
    Because bytes.Reader is a struct, not an Interface. But http.NewRequest takes an io.Reader, which is an interface. You hand it over a type, but with no value -> the interface is not nil.