在golang中,有没有办法看看我是否可以区分json字段被设置为null而json字段在没有编组到结构中时不存在?因为两者都将结构中的值设置为nil,但我需要知道该字段是否在那里开始,并查看是否有人将其设置为null。
{
"somefield1":"somevalue1",
"somefield2":null
}
VS
{
"somefield1":"somevalue1",
}
当解组成结构时,两个jsons都将为nil。 任何有用的资源将非常感谢!
答案 0 :(得分:9)
在决定执行某项操作之前,使用lm.axes[0,0].set_ylim(min(subdf.speed), max(subdf.speed))
“延迟”解组过程以确定原始字节:
json.RawMessage
答案 1 :(得分:4)
如果您将对象解组为map [string] interface {},那么您只需检查字段是否存在
type unMarshalledObject map[string]interface{}
json.Unmarshall(input, unMarshhaledObject)
_, ok := unMarshalledObject["somefield2"]
答案 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