SoFunction
Updated on 2025-03-01

Detailed analysis of problems caused by nil judgment in Go language

Preface

Code encapsulation is something you never get tired of, but sometimes encapsulation can cause some problems. This article records a problem related to nil judgment encountered by individuals when encapsulating http requests.

What is nil

In Go, the zero value of the Boolean type (initial value) is false, the zero value of the numeric type is 0, the zero value of the string type is an empty string "", and the zero value of the pointer, slice, map, channel, function, and interface is nil.

nil is a built-in variable to represent null values, and only pointers, channels, methods, interfaces, maps, and slices can be assigned to nil.

Developers with experience in developing other programming languages ​​may regard nil as null (NULL) in other languages. In fact, this is not completely correct, because nil in Go has many differences from null in other languages.

buildin/:

// nil is a predeclared identifier representing the zero value for a
// pointer, channel, func, interface, map, or slice type.
var nil Type // Type must be a pointer, channel, func, interface, map, or slice type

// Type is here for the purposes of documentation only. It is a stand-in
// for any Go type, but represents the same type for any given function
// invocation.
type Type int

Problem code

The following code is my encapsulation of the method

func (r *Request) Post(endpoint string, params *, body , headers map[string]string, cookies map[string]string) (resp *, err error) {
    url := ("%s%s", , endpoint)
    var req *
    req, err = (, url, body)
    if err != nil {
        return
    }
    (req, params, headers, cookies)
    resp, err = (req)
    return
}

Then when using it like this:

var body *
body = nil

resp, err = (endpoint, nil, body, nil, nil)

At this time, an error of null pointer will occur. Finally, after a long investigation, it was found that it was an error of null pointer in it:

Error analysis

The underlying implementation of pointers and interfaces has two parts: data and type. When the pointer and interface are explicitly assigned to nil, data and type are nil at the same time, but when a value whose type is not nil but data is nil is assigned to the pointer or interface, the result of comparing with nil is false.

Modify the code

Use (body).IsNil() to determine whether the body is empty:

func (r *Request) Post(endpoint string, params *, body , headers map[string]string, cookies map[string]string) (resp *, err error) {
    url := ("%s%s", , endpoint)
    var req *
    if (body).IsNil() {
        req, err = (, url, nil)
    } else {
        req, err = (, url, body)
    }
    if err != nil {
        return
    }
    (req, params, headers, cookies)
    resp, err = (req)
    return
}

Summarize

This is the article about the problem of nil judgment in Go. For more information about Go nil judgment, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!