前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >解决json.Unmarshal无法清空对象字段值

解决json.Unmarshal无法清空对象字段值

原创
作者头像
liliane
修改2021-01-28 00:06:00
2.1K0
修改2021-01-28 00:06:00
举报
文章被收录于专栏:liliane随笔liliane随笔

问题背景

使用 golang 的 json.Unmarshal,将字符串反序列化到对象结构时,若字段原先有值,而被反序列化字符串不包含该字段值,则无法清空对象字段值。

举个例子:

代码语言:go
复制
func TestUnmarshal(t *testing.T) {
    stu := &Student{Age: 11}
	err := json.Unmarshal([]byte(`{"Name": "Lilian"}`), stu)
	if err != nil {
		t.Error(err)
		return
	}
	t.Logf("stu:%+v", *stu)
}

测试结果:(Age 字段保留了原值)

代码语言:javascript
复制
TestUnmarshal: config_test.go:64: stu:{Name:Lilian Age:11}

原因:json Unmarshal 的时候只会更新对应的字段值,字符串未包含 Age 的字段,因此,Age 字段不会被更新。

这种效果在某些情况下是符合预期的,但有些情况,并不是我们希望的结果。例如,在动态同步远程配置的场景。

业务代码自动同步远程配置中心下发的配置变更,将变更的字符串信息 Unmarshal 到目标对象上。当删除配置时,若直接 Unmarshal 到原对象,则无法清空删除配置的字段值。

解决方案

这么常见的问题,大家一定有好的解决方案吧,搜了一下,竟没找到比较好的方案,故简单记录下自己的解决方案,希望有所帮助。

代码语言:javascript
复制
// 根据jsonRaw更新target对象,无论target是否有值,一律清空
func FullUpdate(jsonRaw string, target interface{}) error {
	// 定义一个新对象
	newTargetValue := reflect.New(reflect.TypeOf(target).Elem())
	newTarget := newTargetValue.Interface()
	// 反序列化到新对象上
	err := json.Unmarshal([]byte(jsonRaw), newTarget)
	if err != nil {
		return err
	}
	// 重置目标对象
	reflect.ValueOf(target).Elem().Set(newTargetValue.Elem())
	return nil
}

测试代码:

代码语言:javascript
复制
func TestUnmarshal(t *testing.T) {
	stu := Student{Age: 11}
	str := `{"Name": "Lilian"}`

	FullUpdate(str, &stu)

	t.Logf("stu:%+v", commutil.ToJsonString(stu))
}

测试结果:(Age 字段被清空)

代码语言:javascript
复制
TestUnmarshal: config_test.go:59: stu:{"Name":"Lilian","Age":0}

之所以需要使用 reflect,是因为 target 对象可能已经在其他地方使用了,必须保证该指针指向不变,仅改变指向对象的内容。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题背景
  • 解决方案
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档