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

6

需要检查传递给函数的参数是否为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
}

bean.Request是一个结构体。然而它有问题:"无法将nil转换为类型bean.Request输入请求"。我一直在尝试解决这个问题。

if (bean.Request{})== input

但是它会给出:
"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)

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

2
这里的问题在于问题描述本身:“检查传递给函数的参数是否为nil”。唯一可能为nil的是指针、接口以及切片/映射/通道。如果bean.Request不属于它们中的任何一个,那么问题本身就不太合适。重新阐述问题,明确您想要检查bean.Request上的哪个条件;因为它不可能为空。 - Volker
2个回答

8

简短回答:是的,这里有可用的版本:

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
}

根据您的使用情况,有几种选择(请参见:参数和返回值中指针和值的比较):

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

请参见此示例(在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{}

输出:

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

比较运算符

4- 你可以将变量与其零值进行比较(指针为 nil,如果是 struct 类型,则其零值为 Empty struct,如果结构体类似于 struct{},则其零值不是 nil,而是所有字段初始化为它们的零值)。

零值

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
请查看“reflect.DeepEqual”:如何比较结构体、切片和映射是否相等?
func DeepEqual(x, y interface{}) bool

文档:

 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.

0

是的..错误本身提到它无法比较两者。您可以使用指针与nil进行比较,或创建一个空结构体进行比较。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接