Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 检查struct字段是否为空_Go_Struct_Null - Fatal编程技术网

Go 检查struct字段是否为空

Go 检查struct字段是否为空,go,struct,null,Go,Struct,Null,在将JSON对象解组到结构中之后,我希望迭代该结构的字段,并检查未设置值(即为空)的字段 我可以得到每个字段的值,并将其与相应类型的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 := re

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

我可以得到每个字段的值,并将其与相应类型的
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())) {
    ....
json.Unmarshal([]字节(str),&res)
s:=reflect.ValueOf(&res).Elem()
typeOfT:=s.Type()
对于i:=0;i
但问题当然是,这对
bool
int
值不起作用。 如果在< JSON或<代码> int 中设置<代码> Boo> <代码>字段> false <代码> >字段设置为<代码> 0 >代码>,它们将等于它们的类型的零值。上述检查将考虑未初始化的字段,即使它们实际上有一个值集。


我知道一种解决方法是使用指针,但我不知道在这种情况下如何使用指针,因为我使用的是
reflect.Value
类型,而不是您提到的实际
struct

,您可以使用指针

json
包可以为您处理将值解组为指针的操作。您没有包含要解组的json负载,也没有包含要解组的结构,因此我制作了一个示例

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

// go struct
type Foo struct {
    Present bool `json:"foo"`
    Num     int  `json:"number_of_foos"`
}
这里,如果缺少键
foo
number\u of\u foos
,那么正如您正确观察到的,零值(
false
/
0
)将被使用。一般来说,最好的建议是利用零值。创建结构,以便
false
的零值是有用的,而不是痛苦的。 这并不总是可能的,因此将
Foo
struct中的字段类型更改为指针将允许您检查所需的3种情况

  • 出席
  • 现在和零
  • 失踪
  • 下面是带指针的相同结构:

    // go struct
    type Foo struct {
        Present *bool `json:"foo"`
        Num     *int  `json:"number_of_foos"`
    }
    
    现在,您可以使用
    fooStruct.Present!=nil
    检查是否存在该值,如果该条件成立,您可以假设字段中的值就是您想要的值


    无需使用reflect包。

    另一种方法是实现

    然后,您可以在顶级结构中使用
    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)
    }
    

    查看它在

    上的工作,尝试使用golang validator包。validator包提供了一个必需的属性,可以根据您的需要执行所需的工作。for required属性声明:

    这将验证值是否不是数据类型的默认零值。对于数字,确保值不是零。对于字符串,确保值不是
    “”
    。对于切片、贴图、指针、接口、通道和函数,确保值不是零

    可以在以下位置看到说明相同情况的示例:


    希望这能解决您的需求。

    如果它是一个对象,您可以将其解组到
    map[string]接口{}
    并检查键是否在映射中。我希望能够使用相同的方法来测试
    res
    结构中嵌套的
    结构上的空字段。因此,不幸的是,我认为这不起作用。好吧,你根本不能这样做。不要尝试,你不能。你必须重新设计:或者使用例如
    *bool
    并检查nil或使用map[string]interface{}并检查键是否存在。顺便说一句:Duplicate@user2969402没有任何东西禁止您使用reflect包来检查指针字段是否为nil,因此如果您使用指针,您应该很好。您的最终目标是什么?为什么要这样做?可能有更好的方法。
    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)
    }