检查struct字段是否为空

时间:2018-05-30 06:29:37

标签: go struct null

我希望在将JSON对象解组到其中后迭代struct的字段,并检查其值未设置的字段(即为空)。

我可以获取每个字段的值,并将其与相应类型的reflect.Zero值进行比较

json.Unmarshal([]byte(str), &res)
s := reflect.ValueOf(&res).Elem()
typeOfT := s.Type()
for i := 0; i < s.NumField(); i++ {
    f := s.Field(i)
    v := reflect.ValueOf(f.Interface())
    if (reflect.DeepEqual(v.Interface(), reflect.Zero(v.Type()).Interface())) {
    ....

但问题当然是,这对boolint值不起作用。 如果JSON中的bool字段设置为false,或者int字段设置为0,则它们将等于其类型的零值。上述检查将考虑未初始化的字段,即使它们实际上具有值集。

我知道解决这个问题的一种方法是使用指针,但我只是看不出在这种情况下如何使用reflect.Value类型,而不是实际的struct

3 个答案:

答案 0 :(得分:2)

正如您所提到的,您可以使用指针。

json包可以为您处理指针的解组值。你没有包含你试图解组的json有效负载,或者你正在解组的结构,所以我已经做了一个例子。

// json
{
    "foo": true,
    "number_of_foos": 14
}

// go struct
type Foo struct {
    Present bool `json:"foo"`
    Num     int  `json:"number_of_foos"`
}

如果缺少密钥foonumber_of_foos,那么正如您正确观察到的那样,将使用零值(false / 0)。一般来说,最好的建议是来使用零值。创建结构,使false的零值有用,而不是痛苦。 这并不总是可行的,因此将Foo结构中的字段类型更改为指针将允许您检查您所追求的3个案例。

  1. 目前
  2. 现在和零
  3. 缺少
  4. 这是与指针相同的结构:

    // go struct
    type Foo struct {
        Present *bool `json:"foo"`
        Num     *int  `json:"number_of_foos"`
    }
    

    现在您可以使用fooStruct.Present != nil检查值是否存在,如果该条件成立,您可以假设该字段中的值是您想要的值。

    无需使用反射包。

答案 1 :(得分:1)

另一种方法是实施json.Unmarshaler

type MaybeInt struct {
    Present bool
    Value   int
}

func (i *MaybeInt) UnmarshalJSON(bs []byte) error {
    if e := json.Unmarshal(bs, &i.Value); e != nil {
        return e
    }
    i.Present = true
    return nil
}

然后,您可以在顶级结构中使用MaybeInt

type Top struct {
    N MaybeInt `json:"n"`
    M MaybeInt `json:"m"`
}

func main() {
    t := Top{}
    if e := json.Unmarshal([]byte(` { "n": 4930 } `), &t); e != nil {
        panic(e)
    }
    fmt.Println(t.N, t.M)
}

playground

上查看它

答案 2 :(得分:0)

尝试使用golang验证程序包。验证程序包提供了必需属性,可以根据您的需要执行所需的工作。必需属性的here表示:

  

这验证该值不是数据类型的默认零值。对于数字,确保值不为零。对于字符串,确保值不是+--------+-------+-------+ | Period | Group | Value | +--------+-------+-------+ | 1 | t1 | 0.3 | | 1 | t2 | 0.1 | | 1 | t3 | 0.4 | | 1 | t4 | 0.2 | | 2 | t1 | 0.5 | | 2 | t2 | 0.1 | | 2 | t3 | 0.3 | | 2 | t4 | 0.2 | | ... | ... | ... | +--------+-------+-------+ 。对于切片,贴图,指针,接口,通道和函数,确保值不是零。

可以在official documentation找到说明相同内容的示例。

希望这能解决您的要求。