代码之家  ›  专栏  ›  技术社区  ›  aquiseb

如何检查*结构的所有字段是否为零?

go
  •  1
  • aquiseb  · 技术社区  · 6 年前

    我不太确定如何解决这个问题,请随意编辑。

    使用下面的第一个代码块,我可以检查结构的所有字段是否为零。

    然而,实际上,注入到结构中的值是作为 args。回顾 (参见下面的第二个代码块)。

    在第二个代码块中,如何检查args中的所有字段。审查是否为零?

    Try it on Golang Playground

    package main
    
    import (
        "fmt"
        "reflect"
    )
    
    type review struct {
        Stars      *int32  `json:"stars" bson:"stars,omitempty" `
        Commentary *string `json:"commentary" bson:"commentary,omitempty"`
    }
    
    func main() {
    
        newReview := &review{
            Stars: nil,
            // Stars:   func(i int32) *int32 { return &i }(5),
    
            Commentary: nil,
            // Commentary: func(i string) *string { return &i }("Great"),
        }
    
        if reflect.DeepEqual(review{}, *newReview) {
            fmt.Println("Nothing")
        } else {
            fmt.Println("Hello")
        }
    
    }
    

    Try the second code on Golang Playground 下面的代码有两个错误:

    程序。go:32:14:类型args不是表达式

    程序。转到:44:27:args。审阅不是类型

    package main
    
    import (
        "fmt"
        "reflect"
    )
    
    type review struct {
        Stars      *int32  `json:"stars" bson:"stars,omitempty" `
        Commentary *string `json:"commentary" bson:"commentary,omitempty"`
    }
    
    type reviewInput struct {
        Stars      *int32
        Commentary *string
    }
    
    type args struct {
        PostSlug string
        Review   *reviewInput
    }
    
    func main() {
        f := &args {
            PostSlug: "second-post",
            Review: &reviewInput{
                Stars:  func(i int32) *int32 { return &i }(5),
                Commentary: func(i string) *string { return &i }("Great"),
            },
    
        }
        createReview(args)
    }
    
    func createReview(args *struct {
        PostSlug string
        Review   *reviewInput
    }) {
        g := &review{
            Stars: args.Review.Stars,
            Commentary: args.Review.Commentary,
        }
    
        if reflect.DeepEqual(args.Review{}, nil) {
            fmt.Println("Nothing")
        } else {
            fmt.Println("Something")
        }
    }
    
    1 回复  |  直到 6 年前
        1
  •  5
  •   mkopriva    6 年前

    如果处理的字段数量较少,则应使用simple if 用于确定它们是否 nil 或者不是。

    if args.Stars == nil && args.Commentary == nil {
        // ...
    }
    

    如果您处理的字段比您想在中手动拼写的字段多 如果 语句您可以使用一个简单的助手函数,该函数的变量数为 interface{} 参数。

    func AllNil(vv ...interface{}) bool {
        for _, v := range vv {
            if v != nil {
                return false
            }
        }
        return true
    }
    
    if AllNil(args.Stars, args.Commentary, args.Foo, args.Bar, args.Baz) {
        // ...
    }
    

    或者您可以使用 reflect 包做你的出价。

    func NilFields(x interface{}) bool {
        rv := reflect.ValueOf(args)
        rv = rv.Elem()
    
        for i := 0; i < rv.NumField(); i++ {
            if !rv.Field(i).IsNil() {
                return false
            }
        }
        return true
    }
    
    if NilFields(args) {
       // ...
    }
    

    但请记住: Check for nil and nil interface in Go