json与struct的转换简介熟悉Golang的朋友一定对json与struct的转换不陌生。为了将代码中的结构体和json数据解耦,通常我们会在结构体的字段类型后面加上说明。注意:“结构体的属性首字母必须大写,否则json解析不生效。”typePersonstruct{Namestring`json:"json_key_name"`Ageint`json:"json_key_age"`}funcmain(){Per:=Person{Name:"Xiaofan",Age:18,}res,_:=json.Marshal(Per)fmt.Println(string(res))return}//输出结果{"json_key_name":"Xiaofan","json_key_age":18}结构只初始化了一些变量接下来我们看另外一个Case:p:=Person{Name:"Xiaofan",}res,_:=json.Marshal(p)fmt.Println(string(res))如果我们在初始化结构体的时候只初始化其中一个字段Name,那么理论上,返回的json应该是。{"Name":"Xiaofan"}但是当我们实际运行的时候,返回的结果是。{"Name":"Xiaofan","Age":0}这显然不符合我们的预期,因为我们不需要Age字段。如何解决现在轮到我们今天的主角出场了。解决方法很简单,在后面加上“omitempty”即可。typePersonstruct{NamestringAgeint`json:",omitempty"`}funcmain(){p:=Person{姓名:"小凡",}res,_:=json.Marshal(p)fmt.Println(string(res))}//输出结果的特例{"Name":"Xiaofan"}structure我们再看下面的例子:typePersonstruct{NamestringAgeint}typeStudentstruct{NumintPersonPerson`json:",omitempty"`//对结构person使用omitempty}funcmain(){Stu:=Student{Num:5,}res,_:=json.Marshal(Stu)fmt.Println(string(res))我们为结构体“Person”定义了omitempty,按理说我们在初始化的时候并没有“初始化结构体的任何属性”,所以转换成json后的打印结果应该只是{"Num":5},但是我们实际运行之后,发现打印出来的结果是。{"Num":5,"Person":{"Name":"","Age":0}}为什么“omitempty对结构类型无效”?“这是因为结构体(上例中的Person)并不知道空值是什么,而GO只知道int、string、pointer等简单结构体的空值。”为了不显示我们不提供值体的自定义结构,我们可以使用“structpointer”。为什么这个问题可以用指针类型来解决呢?因为“指针是基本类型,Golang知道它的空值是什么”,所以直接赋值给nil(指针类型的空值)。typePersonstruct{NamestringAgeint}typeStudentstruct{NumintPerson*Person`json:",omitempty"`//如果要omitempty生效,必须是指针type}funcmain(){Stu:=Student{Num:5,}res,_:=json.Marshal(Stu)fmt.Println(string(res))}//输出结果{"Num":5}一个省略的大坑看例子下一步:键入Personstruct{Ageint`json:",omitempty"`}funcmain(){Per:=Person{Age:0,}res,_:=json.Marshal(Per)fmt.Println(string(res))}按照我们的预期,应该给出输出。{"Age":0}是对的,但是我们运行后实际输出的是。{}这显然是个问题。我们需要的是输出的json字段,其中必须有一个age,值为0。现在没有任何输出,显然是有问题的。“因为Golang把0当做零值,所以和没有赋值是一样的。”如果要解决这个问题,一种方法是“使用int指针”,因为int指针的null值为nil,当我要输出0时,我传入地址,地址不能为nullvaluenil,所以它肯定会显示0。json.Marshal(Per)fmt.Println(string(res))}总结omitempty只是在结构体转json的过程中,“只会影响json转换的结果,不会影响结构体本身”,所以对结构体的任何属性设置omitempty后,不影响其正常使用。omitempty的作用简单来说就是“在结构体转json的过程中”,“结构体没有赋值的属性不输出json”。omitempty只支持“简单数据类型”,“结构数据类型无效”。如果需要有效,只能使用“结构指针”。omitempty无法区分“0值、”值和未赋值的值,“如果你给一个属性赋值0或”,想要输出,只能使用指针类型。
