Lets say I have a struct like this (dummy example) :
type Animal struct {
name string
weight int
isLandAnimal boolean
Family
}
type Family struct {
name string
type string
}
Now what I want to achieve is something like this :
var a Animal = ....
bys, err := json.Marshal(a, []string{"name", "Family.name"})
and once printed bys should look like this :
{
"name": "Lion"
"family" : {
"name" : "Felines"
}
}
So I can pass a string slice that references which fields I want to actually get marshaled in the final string.
Does something like this exists in the standard library or in a third party one?
NOTE: This is what I could do based on another SO answer: https://go.dev/play/p/XVb83zoXpmb Will this bring troubles down the road?
CodePudding user response:
You can use tags
type Animal struct {
name string `json:"Family"` // example
weight int `json:"otherthing"` // fill the reset
// ...
}
Although in your example, I would write a custom mapping function, i.e. first unmarshal it to the corresponding type, then have another type for printing, in which you map the values as you see fit.
Something like
func (a *Animal) print() {
showAnimal := DisplayAnimal{name: a.Family.Name}
// add the rest and print it or w/ever you need
}
CodePudding user response:
What you're looking for is struct field annotations for json.Marshal. Basically go expects you to explicitly define the mapping from a struct
to your export object, in this case json
.
You need to ensure that the fields in your struct are exported, or basically start with a capital letter.
Next you can add a annotation to the end of the field to tell go what to look for when unmarshalling, or how to marshal that specific field into the file type format you're looking for.
For example:
This struct with exported members and annotations:
type Cookie struct {
Name string `json:"name"`
Ingredients int `json:"ingredients"`
MilkDunkTime int `json:"milk_dunk_time"`
}
would export into this json:
{
"name": "",
"ingredients: 0,
"milk_dunk_time:" 0
}
I've provided a playground link for your example above with some minor tweaks.
CodePudding user response:
You can annotate the fields which let you specify how it should show up in json and if it needs to be omitted when empty. https://pkg.go.dev/encoding/json#Marshal
Here is a working code. https://pkg.go.dev/encoding/json#Marshal
package main
import (
"encoding/json"
"fmt"
)
type Animal struct {
Name string `json:"name,omitempty"`
Weight int `json:"weight,omitempty"`
IsLandAnimal bool `json:"IsLandAnimal,omitempty"`
Family Family `json:"Family,omitempty"`
}
type Family struct {
Name string `json:"Name,omitempty"`
Familytype string `json:"Familytype,omitempty"`
}
func main() {
a := Animal{Family: Family{Name: "Felines"}, Name: "Lion"}
bys, _ := json.Marshal(a)
fmt.Println(string(bys))
}