How to use Jason's method in Go language?

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.

Keywords: Go

Added by brokencode on Tue, 28 Dec 2021 13:05:42 +0200