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

时间:2018-03-24 15:32:26

标签: go

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

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

实际上,结构中注入的值是 args.Review (参见下面的第二个代码块)。

在第二个代码块中,如何检查args.Review中的所有字段是否为nil?

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 下面的代码有两个错误:

  

prog.go:32:14:type args不是表达式

     

prog.go:44:27:args.Review不是一种类型

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 个答案:

答案 0 :(得分:3)

如果您要处理少量字段,则应使用简单的if语句来确定它们是否为nil

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

如果您处理的字段多于您希望在if语句中手动拼出的字段,则可以使用一个简单的辅助函数,该函数采用可变数量的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