Rudy
Rudy

Reputation: 7044

How to check if parameter passed into function is nil in Go?

Need to check if parameter being passed to func is nil and return 0.

Below is my intended code

func (t *Transaction) GetOperationCount(input bean.Request) (int, error) {
    var result int = 0
    if input == nil { //error here
        return result, nil
    }
    // Other code here!!!!
    return result, nil
}

bean.Reques is a struct. However it had issue: "cannot convert nil to type bean.Request input Request". I have trying

if (bean.Request{})== input

But it gives :

"json:\"MV_STATUS\""; NDFNFFP string "json:\"NDF_NFFP\""; NDFNFMV string "json:\"NDF_NFMV\"" } "json:\"attr\"" } "json:\"marke
t_value\"" } "json:\"market_values\"" } "json:\"tick\"" } "json:\"insertion\"" } "json:\"operation\"" } "json:\"transaction\"" 
} cannot be compared)

Should I change the parameter to "input *bean.Request" ?

Upvotes: 6

Views: 13354

Answers (2)

user6169399
user6169399

Reputation:

Short answer: Yes, here is the working version:

func (t *Transaction) GetOperationCount(input *bean.Request) (int, error) {
    var result int = 0
    if input == nil {
        return result, nil
    }
    // Other code here
    return result, nil
}

You have some options (depending to your use case, see: Pointers vs. values in parameters and return values):

1- You may use pointer (input *bean.Request) and compare it with nil
2- you may use another struct and compare it with reflect.DeepEqual(r, zero)
3- You may write your own compare function (or method with pointer or value receiver)

See this sample (try it on The Go Playground):

package main

import (
    "fmt"
    "reflect"
)

func (t *Transaction) GetOperationCount(input *Request) (int, error) {
    var result int = 0
    if input == nil {
        return result, nil
    }
    // Other code here
    return result, nil
}

func main() {
    var input *Request
    if input == nil {
        fmt.Println("input is nil.") //input is nil.
    }

    input = &Request{}
    if input != nil {
        fmt.Println("input is not nil.") //input is not nil.
    }
    r := Request{}
    fmt.Printf("Zero value: %#v\n", r) //Zero value: main.Request{I:0}

    zero := Request{}
    fmt.Println("r == zero :", r == zero) //r == zero : true

    fmt.Println("DeepEqual :", reflect.DeepEqual(r, zero)) //DeepEqual : true
    fmt.Println("compare   :", compare(&r, &zero))         //compare   : true

}
func compare(r, zero *Request) bool {
    return r.I == zero.I
}

type Request struct {
    I int
}
type Transaction struct{}

output:

input is nil.
input is not nil.
Zero value: main.Request{I:0}
r == zero : true
DeepEqual : true
compare   : true

Comparison operators:

4- You may compare it with its zero value (nil for pointers, and if it is struct it's zero value is Empty struct if it is like struct{} (not nil), or struct with all fields initialized to their zero values):

The zero value:

When storage is allocated for a variable, either through a declaration or a call of new, or when a new value is created, either through a composite literal or a call of make, and no explicit initialization is provided, the variable or value is given a default value. Each element of such a variable or value is set to the zero value for its type: false for booleans, 0 for integers, 0.0 for floats, "" for strings, and nil for pointers, functions, interfaces, slices, channels, and maps. This initialization is done recursively, so for instance each element of an array of structs will have its fields zeroed if no value is specified. These two simple declarations are equivalent:

var i int
var i int = 0

After

type T struct { i int; f float64; next *T }
t := new(T)

the following holds:

t.i == 0
t.f == 0.0
t.next == nil

The same would also be true after

var t T

See "reflect.DeepEqual": How to compare struct, slice, map are equal?

func DeepEqual(x, y interface{}) bool

Docs:

 DeepEqual reports whether x and y are ``deeply equal,'' defined as follows.
 Two values of identical type are deeply equal if one of the following cases applies.
 Values of distinct types are never deeply equal.

 Array values are deeply equal when their corresponding elements are deeply equal.

 Struct values are deeply equal if their corresponding fields,
 both exported and unexported, are deeply equal.

 Func values are deeply equal if both are nil; otherwise they are not deeply equal.

 Interface values are deeply equal if they hold deeply equal concrete values.

 Map values are deeply equal if they are the same map object
 or if they have the same length and their corresponding keys
 (matched using Go equality) map to deeply equal values.

 Pointer values are deeply equal if they are equal using Go's == operator
 or if they point to deeply equal values.

 Slice values are deeply equal when all of the following are true:
 they are both nil or both non-nil, they have the same length,
 and either they point to the same initial entry of the same underlying array
 (that is, &x[0] == &y[0]) or their corresponding elements (up to length) are deeply equal.
 Note that a non-nil empty slice and a nil slice (for example, []byte{} and []byte(nil))
 are not deeply equal.

 Other values - numbers, bools, strings, and channels - are deeply equal
 if they are equal using Go's == operator.

 In general DeepEqual is a recursive relaxation of Go's == operator.
 However, this idea is impossible to implement without some inconsistency.
 Specifically, it is possible for a value to be unequal to itself,
 either because it is of func type (uncomparable in general)
 or because it is a floating-point NaN value (not equal to itself in floating-point comparison),
 or because it is an array, struct, or interface containing
 such a value.
 On the other hand, pointer values are always equal to themselves,
 even if they point at or contain such problematic values,
 because they compare equal using Go's == operator, and that
 is a sufficient condition to be deeply equal, regardless of content.
 DeepEqual has been defined so that the same short-cut applies
 to slices and maps: if x and y are the same slice or the same map,
 they are deeply equal regardless of content.

Upvotes: 8

ganesh kumar
ganesh kumar

Reputation: 146

Yes..The error itself mentions that it cannot compare both. You can use pointer to compare with nil or create an empty struct to compare.

Upvotes: 0

Related Questions