2017-09-17 8 views
0

J'essaye d'écrire un marshaler personnalisé pour un type de base de données probablement nil. Il est structuré exactement la même manière que le type sql.NullFloat64:Omettre JSON pour Empty Custom Type

type NullFloat64 sql.NullFloat64 

func (ni *NullFloat64) MarshalJSON() ([]byte, error) { 
    if !ni.Valid { 
     return []byte("null"), nil 
    } 
    return json.Marshal(ni.Float64) 
} 

Ce qui est une partie de plus struct à marshalés:

type Data struct { 
    X time.Time `json:"x"` 
    Y float32 `json:"y"` 
    Stderr NullFloat64 `json:"stderr"` 
} 

Si je tente de json.Marshal() ce struct, cela fonctionne correctement, création:

{"x":"2017-01-12T23:36:12-05:00","y":4,"stderr":null} 

Je voudrais d'omettre la clé JSON entièrement si la valeur est null . J'ai ajouté json:"stderr,omitempty" à Data.

Par la suggestion here, j'ai essayé juste retourner une valeur nil de MarshalJSON, mais a obtenu:

json: error calling MarshalJSON for type common.NullFloat64: unexpected end of JSON input 

J'ai aussi essayé de mettre à jour Data comme:

type Data struct { 
    X time.Time `json:"x"` 
    Y float32 `json:"y"` 
    Stderr *NullFloat64 `json:"stderr,omitempty"` 
} 

Et marshaling:

Data { 
    X: datetime, 
    Y: value, 
    Stderr: &stderr, 
} 

Mais a eu la même erreur lors du retour nil de MarshalJSON comme avant. Donc, comment puis-je implémenter MarshalJSON pour un type personnalisé et omettre la clé lors du marshaling? Merci pour l'aide!

Répondre

0

Si vous tapez vous créez comme ceci:

Data { 
    X: datetime, 
    Y: value, 
    Stderr: nil, 
} 

omitempty donnera le coup et « faire la bonne chose ». Malheureusement, je suis sûr que cela ne vous aidera pas.

Si vous voulez vraiment omettre un état interne et basé sur un champ, vous devez implémenter json.Marshaller sur votre structure, pas ses enfants. La façon la plus simple de le faire serait la suivante:

func (d Data) MarshalJSON() ([]byte, error) { 
    if !d.Stderr.Valid { 
     return json.Marshal(Data{d.X, d.Y, nil}) 
    } 
    return json.Marshal(d) 
}