Encode
Encode an object into JSON data, accept an interface {} object, and return [] byte and error:
func Marshal(v interface{}) ([]byte, error)
Marshal function will recursively traverse the whole object and encode the object according to the member type in turn. The type conversion rules are as follows:
Boolean type converted to JSON
Integer, floating-point Number and other numerical types are converted to JSON Number
String to JSON string (quoted)
struct is converted to JSON Object, and then recursively packaged according to the type of each member
Array that converts an array or slice to JSON
[] byte will be base64 encoded and then converted to JSON string
map to JSON Object, key must be string
interface {} is converted according to the internal actual type
nil to JSON null
channel,func and other types will return unsupported typeerror
type ColorGroup struct { ID int Name string Colors []string } group := ColorGroup{ ID: 1, Name: "Reds", Colors: []string{"Crimson", "Red", "Ruby", "Maroon"}, } b, err := json.Marshal(group) if err != nil { fmt.Println("error:", err) } os.Stdout.Write(b) Output: {"ID":1,"Name":"Reds","Colors":["Crimson","Red","Ruby","Maroon"]}
Decode
Decoding JSON data
func Unmarshal(data []byte, v interface{}) error
The type conversion rule is similar to the above rule
var jsonBlob = []byte(`[ {"Name": "Platypus", "Order": "Monotremata"}, {"Name": "Quoll", "Order": "Dasyuromorphia"} ]`) type Animal struct { Name string Order string } var animals []Animal err := json.Unmarshal(jsonBlob, &animals) if err != nil { fmt.Println("error:", err) } fmt.Printf("%+v", animals) Output: [{Name:Platypus Order:Monotremata} {Name:Quoll Order:Dasyuromorphia}]
structural morphology
The member whose structure starts with an uppercase letter will be processed by JSON, and the member whose structure starts with a lowercase letter will not be affected.
When Mashal, the member variable name of the structure will be directly packaged into JSON as the key of JSON Object; Unmashal will automatically match the corresponding variable name for assignment, which is case insensitive.
When Unmarshal, if there are redundant fields in JSON, they will be discarded directly; If a field is missing in JSON, it will be ignored directly, and the variable in the structure will not be assigned, and no error will be reported.
type Message struct { Name string Body string Time int64 inner string } var m = Message{ Name: "Alice", Body: "Hello", Time: 1294706395881547000, inner: "ok", } b := []byte(`{"nAmE":"Bob","Food":"Pickle", "inner":"changed"}`) err := json.Unmarshal(b, &m) if err != nil { fmt.Printf(err.Error()) return } fmt.Printf("%v", m) Output: {Bob Hello 1294706395881547000 ok}
StructTag
If you want to manually configure the correspondence between the members of the structure and the JSON field, you can label the members when defining the structure:
If the field is nil or 0 value (number 0, string ", empty array [] and so on), the packed JSON result will not have this field.
type Message struct { Name string `json:"msg_name"` // MSG corresponding to JSON_ name Body string `json:"body,omitempty"` // If it is empty, the field is ignored Time int64 `json:"-"` // Ignore fields directly } var m = Message{ Name: "Alice", Body: "", Time: 1294706395881547000, } data, err := json.Marshal(m) if err != nil { fmt.Printf(err.Error()) return } fmt.Println(string(data)) Output: {"msg_name":"Alice"}
More flexible use of JSON
Use JSON RawMessage
json.RawMessage is actually a redefinition of [] byte type. You can cast.
There is a scenario where the format of one of the fields in the structure is unknown:
type Command struct { ID int Cmd string Args *json.RawMessage }
Use JSON If rawmessage is used, the Args field will not be parsed in Unmarshal, and the byte data will be directly assigned to Args. We can unpack the JSON data of the first layer, and then determine the specific type of Args according to the value of Cmd for the second Unmarshal.
Note here that you must use the pointer type * JSON Rawmessage, otherwise it will be considered as [] byte in Args, and will be packaged into base64 encoded string during packaging.
Using interface {}
When the interface {} type is Unmarshal, JSON will be automatically converted to the corresponding data type:
JSON of boolean Convert to bool JSON Convert the value of to float64 JSON Convert string to string JSON of Array Convert to[]interface{} JSON of Object Convert to map[string]interface{} JSON of null Convert to nil
There are two things to note. One is that all JSON values are automatically converted to float64 type. When used, they need to be manually converted to the required int, int64 and other types. The second is that the JSON object is automatically converted to the map[string]interface {} type. When accessing, the field name of JSON ``Object is directly used as the key. When you no longer know the format of JSON data, you can use interface {}.
Custom type
If you want to define the packaging and unpacking methods of objects, you can implement the following interfaces:
type Marshaler interface { MarshalJSON() ([]byte, error) } type Unmarshaler interface { UnmarshalJSON([]byte) error }
The object implementing the interface needs to package and unpack its own data. If this interface is implemented, json will call custom methods when packaging and unpacking, and no other processing will be performed on this object.