河北高阳做网站的,做技术支持的网站有,WordPress的好处,app制作开发费用多少文章目录 1. 写在最前面2. 字段区分出空字段还是未设置字段2.1 问题描述2.2 解决 3. 字段支持多种类型 按需做不同类型处理3.1 问题描述3.2 解决 4. 碎碎念5. 参考资料 1. 写在最前面
笔者最近在实现将内部通知系统的数据定义转化为产品定义的对外提供的数据结构。 举例… 文章目录 1. 写在最前面2. 字段区分出空字段还是未设置字段2.1 问题描述2.2 解决 3. 字段支持多种类型 按需做不同类型处理3.1 问题描述3.2 解决 4. 碎碎念5. 参考资料 1. 写在最前面
笔者最近在实现将内部通知系统的数据定义转化为产品定义的对外提供的数据结构。 举例说明内部系统数据定义返回的结构定义有如下几种 {magName: uploader, status: 0} {magName: uploaded, fileList: [testa, testb]} {magName: upload_start, fileList: test} {magName: uploading, progress: 1000}
在将如上数据结构转换的时候有两种思路 内部通知系统的数据结构 1:1 跟产品外部定义结构进行映射 内部通知系统的数据结构 n:1 跟产品外部定义的结构进行映射
在进一步拆解问题在做 n:1 映射的时候需要解决的是如何定义一个通用的产品定义结构能够按需根据产品定义进行进行映射。该结构需要解决如下两件事情 fileList 字段可以设置两种不同类型并且支持对改不同类型的返回进行补充 status 字段可以区分出空字段还是未设置字段
2. 字段区分出空字段还是未设置字段
2.1 问题描述
在配置了 omitempty tag 的字段设置的值为默认值时对该字段做 marshal 的时候该字段会被忽略。
例子
package mainimport (encoding/jsonfmt
)type Message struct {Status int json:status,omitemptyMsgName string json:msgName,omitempty
}func main() {//1. status 为默认值 0 时做 unmarshal 可以解析出该字段test : {status: 0, msgName: hello}var m Messageerr : json.Unmarshal([]byte(test), m)if err ! nil {fmt.Println(err)}fmt.Printf(%v\n, m)//2. status 为默认值 0 时做 marshal 时不会输出该字段data, err : json.Marshal(m)if err ! nil {fmt.Println(err)}fmt.Printf(%s\n, data)
}输出
$ go run main.go
unmarshal: {0 hello}
marshal: {msgName:hello}2.2 解决
将可能为默认值的字段设置为指针类型比如 int 设置为 *int
package mainimport (encoding/jsonfmt
)type Message struct {Status *int json:status,omitemptyMsgName string json:msgName,omitempty
}func main() {//1. status 为默认值 0 时做 unmarshal 可以解析出该字段test : {status: 0, msgName: hello}var m Messageerr : json.Unmarshal([]byte(test), m)if err ! nil {fmt.Println(err)}fmt.Printf(unmarshal: %v\n, m)//2. status 为默认值 0 时做 marshal 会输出该字段data, err : json.Marshal(m)if err ! nil {fmt.Println(err)}fmt.Printf(marshal: %s\n, data)
}输出
$ go run main.go
unmarshal: {0x14000110108 hello}
marshal: {status:0,msgName:hello}注设置了指针类型的字段如果原始的字段不存在时则结构体字段为空nil 3. 字段支持多种类型 按需做不同类型处理
3.1 问题描述
某个指定字段支持配置两种类型同时需要不同类型做产品指定的加工处理。
package mainimport (encoding/jsonfmt
)type Message struct {Status *int json:status,omitemptyMsgName string json:msgName,omitemptyFileList any json:fileList,omitempty
}func fixFileList(fileList any) any {switch fileList.(type) {case string:fileList fmt.Sprintf(string type [%s], fileList.(string))return fileListfmt.Printf(fileList: %v\n, fileList)case []interface{}:fileListArr : fileList.([]interface{})for i, _ : range fileListArr {fileListArr[i] fmt.Sprintf(array type [%s], fileListArr[i])}return fileListArr}return unknown
}func main() {//1. FileList 字段为 string 类型test : {status: 0, msgName: hello, fileList: world}var m Messageerr : json.Unmarshal([]byte(test), m)if err ! nil {fmt.Println(err)}m.FileList fixFileList(m.FileList)fmt.Printf(unmarshal 1: %v\n, m)//2. FileList 字段为 array 类型test {status: 0, msgName: hello, fileList: [world, world2]}err json.Unmarshal([]byte(test), m)if err ! nil {fmt.Println(err)}m.FileList fixFileList(m.FileList)fmt.Printf(unmarshal 2: %v\n, m)}输出
$ go run main.go
unmarshal 1: {0x1400000e220 hello string type [world]}
unmarshal 2: {0x1400000e220 hello [array type [world] array type [world2]]}3.2 解决
解决方案分为两个步骤 将该字段设置为 any 或者 insterface 类型 然后在根据断言的类型不同做不同的产品展示结果补充
4. 碎碎念
以上就是关于某次处理脏业务逻辑的包装记录本来还打算把晚上学到的 json inline 用法记录说明一下但是由于本人还没有实践过那就后面用的时候在继续记录吧。 18岁很好28岁也不错38岁可能会更好只要皱纹不长进心里我们就永远风华正茂。 一个女人最重要的能力不是你把自己打扮得多么漂亮也不是你挣钱有多厉害而是无论发生任何事情你都有快乐起来的能力。 当你越来越优秀时你开始明白其实每个人都没有好坏之分没有对错只有频率不同做出了不同的选择。有个好心态路就会走的更宽。
5. 参考资料 Golang 的 “omitempty” 关键字略解 Golang 中使用 JSON 时如何区分空字段和未设置字段