doucandiao9180 2016-09-20 03:04 采纳率: 100%
浏览 351
已采纳

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

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" ?

  • 写回答

2条回答 默认 最新

  • dongyao4003 2016-09-20 03:18
    关注

    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
    ", 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.
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 用visual studi code完成html页面
  • ¥15 聚类分析或者python进行数据分析
  • ¥15 逻辑谓词和消解原理的运用
  • ¥15 三菱伺服电机按启动按钮有使能但不动作
  • ¥15 js,页面2返回页面1时定位进入的设备
  • ¥50 导入文件到网吧的电脑并且在重启之后不会被恢复
  • ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。
  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?