- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
这几天收到一个战术性需求,将一大坨字段序列化为特定格式的字符串.
大概是下表这样:
序号 | 字段名 | 描述 | 是否必填 |
---|---|---|---|
0 | logVersion | 日志版本 | 是 |
1 | productName | 产品 | 是 |
2 | serviceName | 服务 | 是 |
... | |||
... | |||
... | |||
25 | extend3 | 扩展字段3 | 否 |
26 | extend4 | 扩展字段3 | 否 |
27 | extend5 | 扩展字段3 | 否 |
checklist-client com.CommonApiController uploadImage 2017-12-27 10:35:08 378 1.0 null null 192.168.35.12 EBJ4945 null null ylKLPAvAsoaWRnqGZhZ6xqZ6hkYxSrVKsQDOSOpwXgAAAA== 0 91 null null 0 202226d4-255f-891c-b627-9efc28ef366b 0 010 -1 null null null null null null
控制点1:必填字段少,若可选字段无值,该字段序列化为“null”,
控制点2:序列化时只显示字段值(有序),字段之间用空格区分.
这不就是自定义序列化 且设置序列化默认值?
真要我挨个字段填充,我眼睛都要对花, 而且很容易漏掉字段.
// 伪代码如下:
b := bytes.Buffer{}
b.WriteString("P1")
b.WriteString(" ")
b.WriteString("null")
b.WriteString(" ")
b.WriteString("null")
b.WriteString(" ")
b.WriteString("A")
...
b.WriteString(" ")
b.WriteString("null")
log.Info(b.String())
根据"必填字段极少,可选字段默认设为null字符串"的背景,我开始自定义序列化器:
将结构体转换为 map, 这个行为涉及元类型的变动,联想到反射.
自古以来,反射也是兵家必争之地, 于是首次操刀golang的反射特性.
思路和伪代码很明确,实操时还是有2点障碍:
关于第一个问题,利用网上的[提取key放在slice里面,再根据key的排序取map值]的思路是想当然了。 我们的key是字符串, sort.Strings() 之后依旧不是自己的预期( 预期是按照struct字段出现的先后顺序 ).
所以 对map做for循环时,能拿到与struct字段出现顺序一致的键值对 就是关键.
取巧:
我们利用反射struct时的字段顺序,定义了一个按照struct字段出现顺序为键的 map[int]string , 这样 sort.Ints(keys) 排序之后,for map时依旧是我们预期的键值对顺序.
func constructFixedMap(body interface{}) map[int]string {
typ := reflect.TypeOf(body) //TypeOf返回目标数据类型
val := reflect.ValueOf(body) //ValueOf返回目标数据的的值
if typ.Kind() != reflect.Pointer {
fmt.Println("expect pointer")
return nil
}
typ = typ.Elem() // 返回指针所指向的原值
val = val.Elem()
mp := make(map[int]string, 20)
for i := 0; i < typ.NumField(); i++ {
if typ.Field(i).Type.Kind().String() == "string" {
if val.Field(i).String() == "" { // 可选字段,在反射时被修改
mp[i] = "null"
} else {
mp[i] = val.Field(i).String() // 必填字段,保持不变
}
} else {
if val.Field(i).CanInt() {
mp[i] = strconv.FormatInt(val.Field(i).Int(), 10)
} else {
mp[i] = "null"
}
}
}
return mp
}
最后此篇关于自古以来,反射也是兵家必争之地的文章就讲到这里了,如果你想了解更多关于自古以来,反射也是兵家必争之地的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
这几天收到一个战术性需求,将一大坨字段序列化为特定格式的字符串。 大概是下表这样: 序号 字段名 描述 是否必填
好久没上线了,今天记录编程中老掉牙的几个关键术语,一个言简意赅的术语定义包含主谓宾定状补, 我们应从貌似雷同的术语中体会到不同术语的表象行为、侧重点。 下面给出的3对技术术语,都是很核心、易混
我是一名优秀的程序员,十分优秀!