JSON字段设置为null而不是字段

时间:2016-04-13 14:22:11

标签: json go struct null

在golang中,有没有办法看看我是否可以区分json字段被设置为null而json字段在没有编组到结构中时不存在?因为两者都将结构中的值设置为nil,但我需要知道该字段是否在那里开始,并查看是否有人将其设置为null。

{
  "somefield1":"somevalue1",
  "somefield2":null
}

VS

{
  "somefield1":"somevalue1",
}

当解组成结构时,两个jsons都将为nil。 任何有用的资源将非常感谢!

6 个答案:

答案 0 :(得分:9)

在决定执行某项操作之前,使用lm.axes[0,0].set_ylim(min(subdf.speed), max(subdf.speed)) “延迟”解组过程以确定原始字节:

json.RawMessage

查看游乐场https://play.golang.org/p/Wganpf4sbO

答案 1 :(得分:4)

如果您将对象解组为map [string] interface {},那么您只需检查字段是否存在

type unMarshalledObject map[string]interface{}
json.Unmarshall(input, unMarshhaledObject)
_, ok := unMarshalledObject["somefield2"]

Go Playground

答案 2 :(得分:4)

好问题。

我相信你可以使用https://golang.org/pkg/encoding/json/#RawMessage作为:

type MyMessage struct {
  somefield1 string
  somefield2 json.RawMessage
}

因此,在解组后,如果[]byte("null"),则null nil如果遗失,则应private final JPanel buttonPanel = new JPanel(); private final JTextArea listArea = new JTextArea(); //private final JTextArea graphArea = new JTextArea();

这是一个游乐场代码:https://play.golang.org/p/UW8L68K068

答案 3 :(得分:1)

使用自定义类型的另一种方法:

// OptionalString is a struct that represents a JSON string that can be
// undefined (Defined == false), null (Value == nil && Defined == true) or 
// defined with a string value
type OptionalString struct {
    Defined bool
    Value   *string
}

// UnmarshalJSON implements the json.Unmarshaler interface.
// When called, it means that the value is defined in the JSON payload.
func (os *OptionalString) UnmarshalJSON(data []byte) error {
    // UnmarshalJSON is called only if the key is present
    os.Defined = true
    return json.Unmarshal(data, &os.Value)
}


// Payload represents the JSON payload that you want to represent.
type Payload struct {
    SomeField1 string         `json:"somefield1"`
    SomeField2 OptionalString `json:"somefield2"`
}

然后,您可以只使用常规的json.Unmarshal函数来获取值,例如:

    var p Payload
    _ = json.Unmarshal([]byte(`{
            "somefield1":"somevalue1",
            "somefield2":null
        }`), &p)
    fmt.Printf("Should be defined == true and value == nil: \n%+v\n\n", p)


    p = Payload{}
    _ = json.Unmarshal([]byte(`{"somefield1":"somevalue1"}`), &p)
    fmt.Printf("Should be defined == false \n%+v\n\n", p)
    
    p = Payload{}
    _ = json.Unmarshal([]byte(`{
            "somefield1":"somevalue1",
            "somefield2":"somevalue2"
        }`), &p)
    fmt.Printf("Parsed should be defined == true and value != nil \n%+v\n", p)
    if p.SomeField2.Value != nil {
      fmt.Printf("SomeField2's value is %s", *p.SomeField2.Value)
    }

应该给你这个输出:

Should be defined == true and value == nil: 
{SomeField1:somevalue1 SomeField2:{Defined:true Value:<nil>}}

Should be defined == false 
{SomeField1:somevalue1 SomeField2:{Defined:false Value:<nil>}}

Parsed should be defined == true and value != nil 
{SomeField1:somevalue1 SomeField2:{Defined:true Value:0xc000010370}}
SomeField2's value is somevalue2

使用完整示例链接到游乐场:https://play.golang.org/p/AUDwPKHBs62

请注意,您每种要包装的类型都需要一个结构,因此,如果需要一个可选数字,则需要创建一个OptionalFloat64(所有JSON数字可以是64位浮点数)结构,其实现方式与此类似。 如果/当泛型进入Go时,可以将其简化为单个泛型结构。

答案 4 :(得分:0)

如果struct field是一个指针,JSON解码器将在该字段存在时分配新变量,否则保留nil。所以我建议使用指针。

type Data struct {
    StrField *string
    IntField *int
}
...
if data.StrField != nil {
    handle(*data.StrField)
}

答案 5 :(得分:0)

使用github.com/golang/protobuf/ptypes/struct和jsonpb github.com/golang/protobuf/jsonpb,你可以这样做:

func TestFunTest(t *testing.T) {
    p := &pb.KnownTypes{}
    e := UnmarshalString(`{"val":null}`, p)
    fmt.Println(e, p)
    p = &pb.KnownTypes{}
    e = UnmarshalString(`{"val":1}`, p)
    fmt.Println(e, p)
    p = &pb.KnownTypes{}
    e = UnmarshalString(`{"val":"string"}`, p)
    fmt.Println(e, p)
    p = &pb.KnownTypes{}
    e = UnmarshalString(`{}`, p)
    fmt.Println(e, p)
}

输出:

[ `go test -test.run="^TestFunTest$"` | done: 1.275431416s ]
    <nil> val:<null_value:NULL_VALUE > 
    <nil> val:<number_value:1 > 
    <nil> val:<string_value:"string" > 
    <nil> 
    PASS