Convert json strings and various structs to each other
No more nonsense is in the code
package main import ( "fmt" "reflect" "encoding/json" "strings" ) type Class struct { Grade int `json:"grade"` //grade ClassNumber int `json:"classNumber"` //Class number} type Student struct{ Name string //The beginning of capitalization can be exported. Without `json:".."`, the field name of the exported json is the original name age int // Lower case topics cannot be exported Hight int `json:"currentHight"` //Export the field corresponding to json name is currentHight Class *Class `class` //Pointer, pointing to the reference object; if you do not use a pointer, just copy the value} func doMarshal(){//Object to JSON string nClass:=new(Class)//New only allocates memory to specific types, sets the "zero" value, and returns its address (pointer) ("The type of nClass is %s, and the content is %v\n",(nClass),*nClass) =3 =6 nStudents:=make([]*Student,0) //Make is only used for map, slice and channel, and does not display the return pointer //This slice stores the Student's pointer nStudent:=Student{"Lily",7,116,nClass} jsonBytes,err1:=(nStudent)//The parsed is []byte if err1!=nil{ ("Json conversion failed: %v\n",err1) return } ("Converted to JSON:") //age will not be exported //{"Name":"Lily","currentHight":116,"Class":{"grade":3,"classNumber":6}} (string(jsonBytes)) nStudents=append(nStudents,&Student{"Lilei",8,130,nClass}) nStudents=append(nStudents,&nStudent) josnListBytes,err2:=(nStudents) if err2!=nil{ ("Change jsonList failed: %v\n",err2) return } ("Converted to list type JSON:") (string(josnListBytes)) //[{"Name":"Lilei","currentHight":130,"Class":{"grade":3,"classNumber":6}},{"Name":"Lily","currentHight":116,"Class":{"grade":3,"classNumber":6}}] } func doUnMarshal(){//Json string to object jsonStr:=` { "Name":"Lily", "currentHight":116, "age":12, "Class":{ "grade":3, "classNumber":6 }, "score":[98,100,95] } ` jsonListStr:=`[ { "Name":"Lucy", "currentHight":120, "Class":{ "grade":3, "classNumber":5 } }, { "Name":"Lily", "currentHight":116, "Class":{ "grade":3, "classNumber":6 } } ]` //The first method of parsing json, parsing it to Struct/[]Struct student:=Student{}//Same new(Student) err:=([]byte(jsonStr),&student) //The second parameter of Unmarshall must be a pointer, otherwise an error will be reported: json: Unmarshal(non-pointer) //Because the specific object must be parsed, the object reference needs to be passed in, rather than the value passing //score does not have this field in Student, so it is ignored if err!=nil{ ("Parse json string exception: %s\n",err) } ("The student's name is %v, the class information is %v, and the age is %v (private objects cannot be imported, initially 0)\n",,*,) //The student's name is Lily, the student's class information is {3 6}, and the student's age is 0 students:=[]*Student{} //Define the slice, same as make([]*Student,0) err=([]byte(jsonListStr),&students) if err!=nil{ ("Parse json string exception: %s\n",err) } for _,stu:=range students{ // Here stu is the pointer type. You can use .Name directly to obtain its properties, or you can use .Name after dereference. ("List: The student's name is %s, height is %d, in %d grade %d class\n",,(*stu).Hight,(*).Grade,) } //The second type of parsing to interface{}/[]interface{} ("******************Parse json******************") var student1 interface{} err=([]byte(jsonStr),&student1) if err!=nil{ ("Parse json string exception: %s\n",err) } c:=-1 resolve2JosnObj(student1,c) /* ******************Parse json*************** Map element: Element of map[Name]: Type is string, value is Lily Element of map[currentHight]: Type float64, value is 116 Element of map[age]: type float64, value is 12 Elements of map[Class]: map element: --- The element of map[classNumber]: type float64, value is 6 ---Map[grade] element: type float64, value is 3 Element of map[score]: list element: ---0th element: type float64, value is 98 ---The first element: type float64, value is 100 ---The second element: type float64, value is 95 */ ("******************Parse jsonlist***************) var students1 interface{} err=([]byte(jsonListStr),&students1) if err!=nil{ ("Parse jsonlist string exception: %s\n",err) } d:=-1 resolve2JosnObj(students1,d) /* ****************Parse jsonlist************* list element: Element 0: map element: ---Map[Name] element: type is string, value is Lucy --- The element of map[currentHight]: type float64, value is 120 --- Map[Class] element: map element: -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- Element 1: map element: --- Map[Class] element: map element: -------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---Map[Name] element: type is string, value is Lily --- The element of map[currentHight]: type float64, value is 116 */ } func resolve2JosnObj(objI interface{},c int){ c=c+1 switch obj:=objI.(type) { //Here [interface{}].(type) is specially used for switch type judgment case string: ("The type is string, the value is",obj) case float64: ("Type float64, value is",obj) case map[string]interface{}: ("map element:") for k,vi:=range obj{ ("Element of %smap[%s]: ",("---",c),k) resolve2JosnObj(vi,c) } case []interface{}: ("list element:") for i,vi:=range obj{ ("%s%dth element: ",("---",c),i) resolve2JosnObj(vi,c) } default: ("Can't judge the type, the type is",(obj),"Value is",obj) } } func main() { doMarshal()//Object to JSON string doUnMarshal() }
Simple summary
1. Structural object can generate json strings. Marshal() is []byte, and string is required to convert.
2. The json string can be mapped to a struct, but only for public elements (starting from capital); it can also be converted to the empty interface interface[], using the corresponding conversion to the required content
A pitfall in converting structures to JSON strings
When converting structure data into json strings, you need to pay attention to the case of the first letter of the member variables in the structure, which can easily fall into the pit.
Take a look at this example
package main import ( "encoding/json" "fmt" ) type Student struct { Name string age int } func main() { var s Student = Student { Name: "xiaomo", age: 18, } ("%+v\n", s) res, _ := (s) (string(res)) }
The output of the run is as follows:
$ go run test_json.go
{Name:xiaomo age:18}
{"Name":"xiaomo"}
You can see that the converted json string only contains the Name field, and the age field is ignored. This is because when performing json parsing, only fields (capsular) that can be exported by the structure will be converted, and other fields will be ignored.
This mechanism also has an advantage. According to actual needs, you can hide the first letter of the first letter of the field you want to export and the lowercase letter of the other fields.
The above is personal experience. I hope you can give you a reference and I hope you can support me more.