【问题标题】:How to check if parameter passed into function is nil in Go?如何检查传递给函数的参数在Go中是否为零?
【发布时间】:2017-01-27 20:17:50
【问题描述】:

需要检查传递给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
}

bean.Reques 是一个结构体。 但是它有问题:“无法将 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”吗?

【问题讨论】:

  • 这里的问题是问题描述本身:“检查传递给func的参数是否为nil”。 可以为 nil 的只有指针、接口和切片/映射/通道。如果bean.Request 都不是,则问题本身的格式不正确。重新表述问题以明确您要检查bean.Request 上的哪个条件;零是不可能的,

标签: go


【解决方案1】:

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

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
}

您有一些选择(取决于您的用例,请参阅:Pointers vs. values in parameters and return values):

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{}

输出:

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

Comparison operators:

4- 你可以将它与它的零值(指针为零,如果它是struct,它的零值是空结构,如果它像struct{}(不是nil),或者具有所有字段的结构初始化为零值):

The zero value:

当为变量分配存储空间时,无论是通过声明 或调用 new,或在创建新值时,通过 复合文字或 make 调用,并且没有显式初始化 提供,变量或值被赋予默认值。每个元素 这样一个变量或值的类型被设置为零值: false 表示布尔值,0 表示整数,0.0 表示浮点数,"" 表示字符串, 和 nil 用于指针、函数、接口、切片、通道和 地图。这个初始化是递归完成的,所以例如每个 如果没有值,结构数组的元素将其字段归零 被指定。 这两个简单的声明是等价的:

var i int
var i int = 0

之后

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

以下成立:

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

之后也是如此

var t T

参见“reflect.DeepEqual”:How to compare struct, slice, map are equal?

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.

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2016-11-26
      • 2020-11-14
      • 2016-05-07
      • 2022-08-18
      • 2020-01-11
      • 2015-04-06
      • 2018-10-17
      • 2012-01-25
      • 1970-01-01
      相关资源
      最近更新 更多