Using reflection to achievejson
Serialization
type Person struct { Name string `json:"name"` Age int `json:"age"` IsMarraied bool `json:"is_marraied"` } k := map[int]Person{ 1: {Name: "uccs", Age: 18, IsMarraied: false}, 2: {Name: "uccs", Age: 18, IsMarraied: true}, 3: {Name: "uccs", Age: 18, IsMarraied: true}, } s := &[...]interface{}{ 1, &Person{Name: "uccs", Age: 18, IsMarraied: false}, Person{Name: "uccs", Age: 18, IsMarraied: true}, true, Person{Name: "uccs", Age: 18, IsMarraied: true}, }
()
The function is to return a given valueValue of type
Get the valuerv
After that, use().Kind()
You can get the underlying type of the value passed by the user
()
The value obtained isType, cannot be used to judge, so it needs to be used
().Kind()
Get it
Judge int type
int
Types areint
、int8
、int16
、int32
、int64
,return("%v", ())
func JsonMarshal(v interface{}) (string, error) { rv := (v) rt := () switch () { case , reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return ("%v", ()), nil default: return "", ("unsupported type: %s", rt) } }
Determine float type
float
Types arefloat32
andfloat64
,return("%v", ())
func JsonMarshal(v interface{}) (string, error) { rv := (v) rt := () switch () { case reflect.Float32, reflect.Float64: return ("%v", ()), nil default: return "", ("unsupported type: %s", rt) } }
Judge string type
string
Type, return("%q", ())
func JsonMarshal(v interface{}) (string, error) { rv := (v) rt := () switch () { case : return ("%q", ()), nil default: return "", ("unsupported type: %s", rt) } }
Judge bool type
bool
Type, return("%v", ())
func JsonMarshal(v interface{}) (string, error) { rv := (v) rt := () switch () { case : return ("%v", ()), nil default: return "", ("unsupported type: %s", rt) } }
Determine the slice type
slice
The type can be simply understood as an array, and the returned type is an arrayjson
String
func JsonMarshal(v interface{}) (string, error) { rv := (v) rt := () switch () { case : return marshalSlice(rv) default: return "", ("unsupported type: %s", rt) } }
deal withslice
The process package ismarshalSlice
function
Need to go throughslice
To get the content of each item, you can use `(i).Interface()
Then calljsonMarshal
Function, passed inslice
Recursively process each item
Finally, the array format is splicedjson
string, use(items, ",")
Splicing
func marshalSlice(rv ) (string, error) { var items []string for i := 0; i < (); i++ { value, err := JsonMarshal((i).Interface()) if err != nil { return "", err } items = append(items, value) } return "[" + (items, ",") + "]", nil }
Judge array type
deal witharray
Types and processingslice
It's the same, just need toarray
Convert toslice
, can be used in reflection(0, ())
func JsonMarshal(v interface{}) (string, error) { rv := (v) rt := () switch () { case : return marshalSlice((0, ())) default: return "", ("unsupported type: %s", rt) } }
Judge struct type
struct
The type is similar to an object, and the returned type is the objectjson
String
func JsonMarshal(v interface{}) (string, error) { rv := (v) rt := () switch () { case : return marshalStruct(rv) default: return "", ("unsupported type: %s", rt) } }
deal withstruct
The process is encapsulated asmarshalStruct
Function
Let's define a structure first
type Person struct { Name string `json:"name"` Age int `json:"age"` isMarraied bool `json:"is_marraied"` }
There are two things to note in this structure:
- Attributes starting with lowercase letters, no serialization is required
- according to
json_tag
to serialize the value of
passGet all the properties in the structure and use
for
Loop traversal
pass(i)
Get the value of the attribute, through().Field(i).("json")
Get itjson
The value of the tag
If the attribute name starts with lowercase letters, no serialization is required, just skip it, and passisFieldExported
Function completion
func isFieldExported(name string) bool { r, _ := (name) return (r) }
Then calljsonMarshal
Functions, pass into each item in the structure, recursively processed
Finally, splicing out the array formatjson
String, use(items, ",")
Splicing
func marshalStruct(rv ) (string, error) { var items []string for i := 0; i < (); i++ { fieldValue := (i) jsonTag := ().Field(i).("json") key := ().Field(i).Name if !isFieldExported(key) { continue } if jsonTag != "" { key = jsonTag } value, err := JsonMarshal(()) if err != nil { return "", err } items = append(items, ("%q:%v", key, value)) } return "{" + (items, ",") + "}", nil }
Handle pointer types
deal withpointer
Type, you need to judge firstpointer
Types to be pointed to
- in the case of
array
Type, need to bepointer
Convert toslice
, and then callmarshalSlice
function - in the case of
struct
Type, call directlymarshalStruct
func JsonMarshal(v interface{}) (string, error) { rv := (v) rt := () switch () { case : if ().Kind() == { return marshalSlice(().Slice(0, ())) } if ().Kind() == { return JsonMarshal(().Interface()) } return JsonMarshal(().Interface()) default: return "", ("unsupported type: %s", rt) } }
Corresponding source code:to_json
This is the article about the example code in Go using reflect to implement json serialization. For more related go reflect json serialization content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!