Go使用类型断言处理动态JSON字段

Go作为强类型语言,在序列化和反序列化过程中,都不可避免地需要定义结构体:在有IDL的情况下结构体可以使用工具自动生成(kitex),在无IDL的情况下就得手撸。

动态JSON字段

 {
	"fields":[
		{
			"field_name": "名称",
			"field_value":"示例文字string类型"
		},
		{
			"field_name": "属性",
			"field_value":{
				"label":"示例map_key",
				"value":"示例map_value"
			}
		}
	]
 }

如图所示,fields数组内具体的field_value字段,可能是string类型,也有可能是map类型(或者也可以定义为存在Label和Value两个字段的结构体,这里为了更通用化,定义为map[string]string)

如何处理

目前google能得到最好的解决方法参见这篇文章:如何处理动态JSON in Go,结构体最外层专门有一个字段type标明其他字段类型,然后根据type指示的类型,使用golang提供的type swith语句分别进行处理。type switch语句是go独有的在多个case语句中提供多种类型断言,每种类型分别处理的结果。

这种方法在结合具体业务代码时看上去有些复杂(遍历fields时每次处理都伴随type switch语句)。

本篇博客介绍一种写法更加简单的直接基于类型断言的方法,供golang新手参考。

类型断言

类型断言(Type Assertion)是一个使用在接口值上的操作,用于检查接口类型变量所持有的值是否实现了期望的接口或者具体的类型。

完整的使用方法:

value, ok := x.(T)

如果变量x真的是T类型,那么ok返回true,否则返回false,可以再根据ok的值编写进一步的处理逻辑

实际使用中,如果能确信x的类型,可以直接写:

value := x.(T)

value中存储了x(类型为interface{},即任何类型)类型为T的值。

直接使用类型断言处理动态JSON

首先我们定义field字段为golang中的万用类型interface{}

type Fields []Field

type Field struct {
	FieldName    string      `json:"field_name"`
	FieldValue   interface{} `json:"field_value"`
}

接着在for循环遍历过程中直接使用类型断言转化为具体的类型:

for _, field := range node.Fields {
	if field.FieldName == "名称" {
		object[field.FieldName] = field.FieldValue.(string)
	} else if field.FieldName == "属性" {
		object[field.FieldName] = field.FieldValue.(map[string]interface{})["label"].(string)
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值