SoFunction
Updated on 2025-03-05

Sample code for implementing JSON serialization using reflect in go

Using reflection to achievejsonSerialization

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 valuervAfter 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

intTypes areintint8int16int32int64,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

floatTypes arefloat32andfloat64,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

stringType, 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

boolType, 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

sliceThe type can be simply understood as an array, and the returned type is an arrayjsonString

func JsonMarshal(v interface{}) (string, error) {
  rv := (v)
  rt := ()
  switch () {
  case :
    return marshalSlice(rv)
  default:
    return "", ("unsupported type: %s", rt)
  }
}

deal withsliceThe process package ismarshalSlicefunction

Need to go throughsliceTo get the content of each item, you can use `(i).Interface()

Then calljsonMarshalFunction, passed insliceRecursively process each item

Finally, the array format is splicedjsonstring, 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 witharrayTypes and processingsliceIt's the same, just need toarrayConvert 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

structThe type is similar to an object, and the returned type is the objectjsonString

func JsonMarshal(v interface{}) (string, error) {
  rv := (v)
  rt := ()
  switch () {
  case :
    return marshalStruct(rv)
  default:
    return "", ("unsupported type: %s", rt)
  }
}

deal withstructThe process is encapsulated asmarshalStructFunction

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 tojson_tagto serialize the value of

passGet all the properties in the structure and useforLoop traversal

pass(i)Get the value of the attribute, through().Field(i).("json")Get itjsonThe value of the tag

If the attribute name starts with lowercase letters, no serialization is required, just skip it, and passisFieldExportedFunction completion

func isFieldExported(name string) bool {
  r, _ := (name)
  return (r)
}

Then calljsonMarshalFunctions, pass into each item in the structure, recursively processed

Finally, splicing out the array formatjsonString, 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 withpointerType, you need to judge firstpointerTypes to be pointed to

  • in the case ofarrayType, need to bepointerConvert toslice, and then callmarshalSlicefunction
  • in the case ofstructType, 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!