2017-08-16 1 views
1

Ich möchte einen Fehler ausgeben, wenn das Feld in JSON einen Wert von Null enthält. Wie kann ich es tun? Ich habe "encoding/json" ausprobiert. Vielleicht brauche ich eine andere Bibliothek.Wie kann ich wissen, dass das Feld auf Null gesetzt ist?

Code-Beispiel:

package main 

import (
    "encoding/json" 
    "fmt" 
    "strings" 
) 

type Item struct { 
    Value *int 
} 


func main() { 
    var jsonBlob = `[ 
     {}, 
     {"Value": null}, 
     {"Value": 0}, 
     {"Value": 1} 
    ]` 
    var items []Item 

    err := json.NewDecoder(strings.NewReader(jsonBlob)).Decode(&items) 
    if err != nil { 
     fmt.Println("error:", err) 
    } 
    for _, a := range items { 
     if a.Value != nil { 
      fmt.Println(*a.Value) 
     } else { 
      fmt.Println(a.Value) 
     } 
    } 
} 

Ich habe:

<nil> 
<nil> 
0 
1 

Ich möchte:

<nil> 
<error> 
0 
1 

Bitte helfen. Danke vielmals!

+0

Warum sollte ' "Wert": null' zu einem Fehler führen? 'null' ist ein vollkommen gültiger Wert für ein Zeigerfeld und wird korrekt zu' nil' deserialisiert, was Go's 'null' ist. – Adrian

+0

Ich schreibe Rest-api. Dies ist eine der Voraussetzungen. – Ilya

+0

@Ilya: Dies scheint wie eine seltsame Voraussetzung für eine API, "Null" und Unset sind oft die gleiche Sache. – JimB

Antwort

4

Wenn Sie steuern möchten, wie ein Typ unmarshal ist, können Sie json.Unmarshaler

implementieren Da eine Karte, die Sie den Unterschied zwischen einem ungesetzt Wert zu sagen erlaubt, und ein null Wert, Deserialisieren zunächst in eine generische map[string]interface{} erlaubt Sie können die Werte prüfen, ohne den JSON zu Tokenisieren.

type Item struct { 
    Value *int 
} 


func (i *Item) UnmarshalJSON(b []byte) error { 
    tmp := make(map[string]interface{}) 

    err := json.Unmarshal(b, &tmp) 
    if err != nil { 
     return err 
    } 

    val, ok := tmp["Value"] 
    if ok && val == nil { 
     return errors.New("Value cannot be nil") 

    } 
    if !ok { 
     return nil 
    } 

    f, ok := val.(float64) 
    if !ok { 
     return fmt.Errorf("unexpected type %T for Value", val) 
    } 

    n := int(f) 
    i.Value = &n 
    return nil 
} 

https://play.golang.org/p/MNDsQpfEJA

+0

Ich glaube nicht, dass dies funktioniert, je nach der Frage, sie wollen den Null-Wert zu "Null" aber Null-Wert zu einem Fehler führen, nach dem "Ich will" Abschnitt in der Frage. – Adrian

+0

@Adrian: ah, danke. Ich kümmere mich darum – JimB

+0

@Ilya: Ich habe mit einer Karte Beispiel aktualisiert, die zeigt, wie "Unset" vs "Null" zu unterscheiden – JimB

Verwandte Themen