结构体 转换成json时nil转为null,其实就是nil转换成json就是null
1,某结构体的普通字段,可以在json标签里面加omitempty,这样某个字段如果没有值,就不返回
2,某结构体数组中的的子结构体字段,var tags_list []*models.BugTags 改为 tags_list := make([]*models.BugTags, 0)
3,在Go中,如果你尝试访问一个map中不存在的key,它将会返回map类型的值对应的零值。对于大多数map的value类型,零值为nil。比如interface{}
初始化:
如果初始化结构体,默认所有字段取0值;初始化结构体指针,默认nil
这两个初始化的方式有一定的区别。
params := &models.Cve5CollectionLogParam{}:这种初始化方式使用了短变量声明,通过&符号创建了一个指向models.Cve5CollectionLogParam类型零值的指针。这样做后,params就是一个指针类型的变量,可以直接对其字段进行操作。
var params *models.Cve5CollectionLogParam:这种初始化方式声明了一个指针类型的变量params,但是没有对其进行初始化。此时,params的值为nil,即指针不指向任何有效的内存地址。
如果在第二种初始化方式之后直接对params的字段进行赋值操作,会导致空指针错误。因为params是一个空指针,没有指向任何实际的对象或数据。解决这个问题的方法是先为params分配一块内存,并将其指向该内存地址,然后再对其字段进行赋值,如下所示:
go
params := &models.Cve5CollectionLogParam{}
params.Limit = pageNum
params.Offset = (page - 1) * pageNum
或者使用new函数为params分配内存并返回一个指向该内存地址的指针,然后对其字段进行赋值:
go
params := new(models.Cve5CollectionLogParam)
params.Limit = pageNum
params.Offset = (page - 1) * pageNum
通过以上方式,可以避免空指针错误,并正常对params的字段进行赋值操作。
json
|
|
CvssV20 CvssV20 `json:"cvssV2_0,omitempty" bson:"cvssV2_0,omitempty"` |
|
|
type CvssV20 struct { BaseCvss `bson:",inline"` AccessVector string `json:"accessVector,omitempty" bson:"accessVector,omitempty"` AccessComplexity string `json:"accessComplexity,omitempty" bson:"accessComplexity,omitempty"` Authentication string `json:"authentication,omitempty" bson:"authentication,omitempty"` } |
如上所示,omitempty 是一个选项,用于指示当字段的值为空值或零值时(例如指针为 nil、字符串为空字符串等),JSON序列化或BSON序列化时应该省略该字段。这种选项每个库都有不同,比如bson库还有一个inline,用于在入库出库时,忽略本节点层级,直接使用本节点属性。
需要注意的是,omitempty 仅适用于在序列化时省略字段。在反序列化时,无论字段是否有值,都会正确地解析到结构体中。具体表现就是如果设置该字段,入库没有该值会不入库本字段,但是出库数据会映射空值。
想要出库时也不映射空置,要把CvssV20改为指针形式。
- 序列化:将数据结构或对象转换为可以存储或传输的格式,例如将一个结构体转换为JSON字符串。序列化过程将数据转换为特定的格式,以便其在存储或传输时可以被还原回原始的数据结构。
- 反序列化:将序列化后的数据重新转换回原始的数据结构或对象。例如,将一个JSON字符串解析为相应的结构体。反序列化过程将序列化的数据解析并填充到适当的数据结构中。
结构体中的切片字段,如果为nil(也就是没显示初始化,比如从数据库取数据没有映射到),会在json序列化时,转换为null
但是如果切片字段显示初始化了,但是没有赋值,比如var a []int,这时候json序列化时,会转换为[]
这个函数的作用就是,把结构体中的切片字段,如果为nil,就初始化为[],这样json序列化时,就会转换为[]
比较方便前端处理
运用了递归和反射
|
|
func InitSliceFields(data interface{}) { initSliceField(reflect.ValueOf(data).Elem()) } func initSliceField(value reflect.Value) { for i := 0; i < value.NumField(); i++ { fieldValue := value.Field(i) if fieldValue.Type().Kind() == reflect.Slice && fieldValue.IsNil() { fieldValue.Set(reflect.MakeSlice(fieldValue.Type(), 0, 0)) } else if fieldValue.Kind() == reflect.Struct { initSliceField(fieldValue) } } } |
6666
「三年博客,如果觉得我的文章对您有用,请帮助本站成长」
共有 0 - golang 变量声明和json转换