2016-04-13 17 views
7

golangに、jsonフィールドとnullに設定されているjsonフィールドとjsonフィールドが構造体にアンマーシャリングされていないと区別できるかどうかを確認する方法はありますか?両方ともstructの値をnilに設定しているので、フィールドがあるかどうかを知り、誰かがnullに設定しているかどうかを知る必要があります。構造体の中に非整列化するときGolang - JSONフィールドがヌルに設定されているフィールドとそこにはありません

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

VS

{ 
    "somefield1":"somevalue1", 
} 

どちらjsonsはnilになります。 有用なリソースは非常に高く評価されます!

答えて

6

使用json.RawMessage:ここ

は遊び場コードです

var data = []byte(`{ 
     "somefield1":"somevalue1", 
     "somefield2": null 
}`) 

type Data struct { 
    SomeField1 string   
    SomeField2 json.RawMessage 
} 

func main() { 
    d := &Data{} 

    _ = json.Unmarshal(data, &d) 

    fmt.Println(d.SomeField1) 

    if len(d.SomeField2) > 0 { 
     if string(d.SomeField1) == "null" { 
      fmt.Println("somefield2 is there but null") 
     } else { 
      fmt.Println("somefield2 is there and not null") 
      // Do something with the data 
     } 
    } else { 
     fmt.Println("somefield2 doesn't exist") 
    } 
} 

は遊び場https://play.golang.org/p/Wganpf4sbO

+0

申し訳ありませんが、私は移動する初心者です、と私は確信していませんが、SomeField2が "こんにちは"と言う場合、これはnullではないとは思わないでしょうか? –

+1

いいです、少し編集が必要です - https://play.golang.org/p/UW8L68K068 –

+1

@AlexanderTrakhimenokコメントを編集してくれてありがとうございました。 – PieOhPah

2

あなたがマップ[文字列]インターフェース{}の中にオブジェクトをアンマーシャリングした場合、フィールドが

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

Go Playground

+2

'マップ[文字列]インターフェース{}'の使用:

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) } 

出力この場合、過剰殺害であり、過度に複雑である。 – PieOhPah

+0

@ pie-o-pahと合意すれば、これはsomefield1のタイプを隠すでしょうが、それが全く動作していることを知ることは非常に面白いです。 –

3

良い質問であれば、あなたはただ確認することができます。だから、不足している場合はnullnilの場合に[]byte("null")を持つべきである非整列化した後

type MyMessage struct { 
    somefield1 string 
    somefield2 json.RawMessage 
} 

私はあなたのようhttps://golang.org/pkg/encoding/json/#RawMessageを使用することができると信じています。何かを決定する前に生のバイトを決定するために、「遅延」アンマーシャリング・プロセスにhttps://play.golang.org/p/UW8L68K068

0

を参照してください。 structフィールドがポインタの場合、JSONデコーダはフィールドがある場合は新しい変数を割り当て、そうでない場合はnilにします。だから私はポインタを使用することをお勧めします。 github.com/golang/protobuf/ptypes/structとjsonpb github.com/golang/protobuf/jsonpbを使用することにより

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

、あなたは次のように行うことができます:面白いものの、

[ `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 
関連する問題