检查结构体字段是否为空

use*_*402 6 null struct go

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

我可以获取每个字段的值并将其与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())) {
    ....
Run Code Online (Sandbox Code Playgroud)

但问题当然是这对于boolint值来说效果不佳。如果JSON 中的bool字段设置为或字段设置为,则它们将等于其类型的零值。上述检查将认为这些字段未初始化,即使它们实际上设置了值。falseint0

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

Zak*_*Zak 8

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

json包可以为您处理将值解组为指针的操作。您还没有包含您尝试解组的 json 有效负载,或者您要解组的结构,因此我编写了一个示例。

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

// go struct
type Foo struct {
    Present bool `json:"foo"`
    Num     int  `json:"number_of_foos"`
}
Run Code Online (Sandbox Code Playgroud)

在这里,如果缺少键foo或,那么正如您所正确观察到的那样,将使用零值( / )。一般来说,最好的建议是使用零值。创建结构,使 的零值有用,而不是痛苦。这并不总是可能的,因此将结构中的字段类型更改为指针将允许您检查后面的 3 种情况。number_of_foosfalse0falseFoo

  1. 展示
  2. 现在和零
  3. 丢失的

这是带有指针的相同结构:

// go struct
type Foo struct {
    Present *bool `json:"foo"`
    Num     *int  `json:"number_of_foos"`
}
Run Code Online (Sandbox Code Playgroud)

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

不需要使用reflect包。