代码之家  ›  专栏  ›  技术社区  ›  Schidu Luca

JSON解组中缺少字段和空字段之间的区别

  •  0
  • Schidu Luca  · 技术社区  · 6 年前

    所以我有一个结构:

    type Car struct {
        Name  string `json:"name"`
        Speed int    `json:"speed"`
    }
    

    我有两个JSON示例进行解组:

    str := `{"name": "", "speed": 0}`
    strTwo := `{}`
    

    我这样做解组:

    car := Car{}
    _ = json.Unmarshal([]byte(str), &car)
    
    carTwo := Car{}
    _ = json.Unmarshal([]byte(strTwo), &carTwo)
    

    现在,由于Go处理默认值类型的方式,当我试图打印结构时,得到的结果是相同的:

    car - { 0}
    carTwo - { 0}
    

    type Car struct {
        Name  *string `json:"name"`
        Speed *int    `json:"speed"`
    }
    

    但是当我用一个指针去引用所有的值时

    0 回复  |  直到 6 年前
        1
  •  2
  •   icza    6 年前

    Go的原始数据类型不适合处理“所有有效值”和附加的“is present”信息。

    nil 指针值对应于“缺少”状态。

    如果以后使用指针不舒服,请执行“后处理”:将带有指针字段的结构转换为带有非指针字段的结构值,以便以后可以使用它。

    下面是一个如何操作的示例:

    type PCar struct {
        Name  *string `json:"name"`
        Speed *int    `json:"speed"`
    }
    
    type Car struct {
        Name  string `json:"-"`
        Speed int    `json:"-"`
        PCar
    }
    
    func (c *Car) UnmarshalJSON(data []byte) error {
        if err := json.Unmarshal(data, &c.PCar); err != nil {
            return err
        }
    
        if c.PCar.Name != nil {
            c.Name = *c.PCar.Name
        }
        if c.PCar.Speed != nil {
            c.Speed = *c.PCar.Speed
        }
        return nil
    }
    

    使用示例:

    sources := []string{
        `{"name": "", "speed": 0}`,
        `{}`,
        `{"name": "Bob", "speed": 21}`,
    }
    
    for i, src := range sources {
        var c Car
        if err := json.Unmarshal([]byte(src), &c); err != nil {
            panic(err)
        }
        fmt.Println("car", i, c)
    }
    

    Go Playground ):

    car 0 { 0 {0x40c200 0x4140ac}}
    car 1 { 0 {<nil> <nil>}}
    car 2 {Bob 21 {0x40c218 0x41410c}}
    

    car 1 包含2个非- car 2 包含2个 Car.Name Car.Speed 字段作为非指针(因为它们不是指针)。要判断它们是否存在于输入中,您可以检查相应的指针 Car.PCar.Name Car.PCar.Speed 如果是的话 .