如何在Go中检查传递给函数的参数是否为nil?

Rud*_*udy 3 go

需要检查传递给func的参数是否为nil并返回0。

下面是我的预期代码

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
}
Run Code Online (Sandbox Code Playgroud)

bean.Reques是一个结构。但是它有一个问题:“不能将nil转换为bean.Request输入Request类型”。我尝试了

if (bean.Request{})== input
Run Code Online (Sandbox Code Playgroud)

但是它给出了:

"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)
Run Code Online (Sandbox Code Playgroud)

我应该将参数更改为“ input * bean.Request”吗?

小智 5

简短答案:是的,这是工作版本:

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
}
Run Code Online (Sandbox Code Playgroud)

您有一些选择(取决于您的用例,请参见:指针与参数中的值以及返回值):

1-您可以使用指针(input *bean.Request)并将其与nil
2- 比较,您可以使用其他结构并将其与reflect.DeepEqual(r, zero)
3-可以编写自己的compare函数(或具有指针或值接收器的方法)

请参阅此示例(在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{}
Run Code Online (Sandbox Code Playgroud)

输出:

input is nil.
input is not nil.
Zero value: main.Request{I:0}
r == zero : true
DeepEqual : true
compare   : true
Run Code Online (Sandbox Code Playgroud)

比较运算符

4-您可以将其与其零值进行比较(如果为指针,则为nil,如果struct为零,则为空struct(如果struct{}不是nil),或者将所有字段初始化为零值的struct):

零值

当通过声明或调用new为变量分配存储空间时,或者通过复合文字或make调用创建新值时,并且未提供任何显式初始化时,将给出变量或值默认值。此类变量或值的每个元素均将其类型设置为零值:布尔值为false,整数值为0,浮点数为0.0,字符串为“”,指针,函数,接口,切片,通道和映射为nil 。此初始化是递归完成的,因此,例如,如果未指定任何值,则结构数组的每个元素的字段都将为零。这两个简单的声明是等效的:

var i int
var i int = 0
Run Code Online (Sandbox Code Playgroud)

type T struct { i int; f float64; next *T }
t := new(T)
Run Code Online (Sandbox Code Playgroud)

以下内容成立:

t.i == 0
t.f == 0.0
t.next == nil
Run Code Online (Sandbox Code Playgroud)

之后也是如此

var t T
Run Code Online (Sandbox Code Playgroud)

请参见“ reflect.DeepEqual”:如何比较struct,slice,map是否相等?

func DeepEqual(x, y interface{}) bool
Run Code Online (Sandbox Code Playgroud)

文件:

 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.
Run Code Online (Sandbox Code Playgroud)