首页>>后端>>Golang->Golang实践录:反射reflect的一些研究及代码汇总

Golang实践录:反射reflect的一些研究及代码汇总

时间:2023-12-01 本站 点击:0

本文汇总一些工程中使用到的和 reflect 有关的代码示例。由于是代码片段,不一定保证完整。但其思想可以参考。

解析json

本节介绍解析json的一些方法。json 可来自文件,也可来自字符串,无论哪种,都是先转换成[]byte,再调用json.Unmarshal解析。 有时候并不关注完整的 json 格式,因为完整的 json 数据可能非常多,而我们只需其中一个字段或部分字段,因此,可使用map[string]interface{}来接收解析结果(注意如果 json 本身是数组,则 map 必须使用数组形式)。

从json文件解析其字段

首先打开文件,再读取其内容,再调用json.Unmarshal即可。

file,err:=os.Open(filename)iferr!=nil{fmt.Printf("openfile%serror:%s\n",filename,err)return}deferfile.Close()read:=io.Reader(file)data,_:=ioutil.ReadAll(read)varv[]map[string]interface{}err=json.Unmarshal(data,&v)iferr!=nil{fmt.Printf("Unmarshalerror:%s\n",err)return}//假定filename里面有很多的json数组,一一遍历for_,idx:=rangev{fmt.Println(idx["foo"])...}

从json字符串解析

一个简单的示例,从字符串组装,到解析,到提取其中某个字段。

funcTestJsonSimple(t*testing.T){//原始json字符串不能格式化,必须转换成[]byteorgJsonString:=`{"enID":"ID250","exID":"ID251","type":1,"money":250.44,"distance":274050}`//虽然不知道具体结构体,但知道json只有一个,不是数组vardatamap[string]interface{}//解析err:=json.Unmarshal([]byte(orgJsonString),&data)iferr!=nil{fmt.Println(err.Error())return}fmt.Printf("%#v\n",data);fmt.Println(data["money"])//并不关心其它字段,只抽取所需的fmt.Println(data["money1"])//不存在,返回nil}

输出如下内容:

map[string]interface{}{"distance":274050,"enID":"ID250","exID":"ID251","money":250.44,"type":1}250.44<nil>

如果 json 中有嵌套的数组,获取数组内容代码如下:

funcshowInterface(origininterface{}){switchreflect.TypeOf(origin).Kind(){casereflect.Slice,reflect.Array:s:=reflect.ValueOf(origin)fori:=0;i<s.Len();i++{fmt.Printf("%d:%v\n",i,s.Index(i))}casereflect.String:s:=reflect.ValueOf(origin)fmt.Printf("onlystring%v\n",s.String())casereflect.Int:s:=reflect.ValueOf(origin)fmt.Printf("onlyint%v\n",s.Int())}}funcTestJsonArray(t*testing.T){orgJsonString:=`{"enID":"ID500","exID":"ID501","type":2,"money":27.00,"distance":28322,"splitInfo":[{"index":1,"pTag":"11","pMoney":700},{"index":2,"pTag":"12","pMoney":2000}]}`//解析vardatamap[string]interface{}err:=json.Unmarshal([]byte(orgJsonString),&data)iferr!=nil{fmt.Println(err.Error())return}fmt.Printf("orgjson:\n%#v\n\n",data);showInterface(data["enID"])showInterface(data["splitInfo"])}

data["splitInfo"]是一个interface,此刻并不知道具体的内容,因此无法再获取内部的字段或长度。可以利用reflect.TypeOf获取类型,如是数组,需要遍历。详见代码。 输出内容如下:

orgjson:map[string]interface{}{"distance":28322,"enID":"ID500","exID":"ID501","money":27,"splitInfo":[]interface{}{map[string]interface{}{"index":1,"pMoney":700,"pTag":"11"},map[string]interface{}{"index":2,"pMoney":2000,"pTag":"12"}},"type":2}onlystringID5000:map[index:1pMoney:700pTag:11]1:map[index:2pMoney:2000pTag:12]

接上,如果只需要获取data["splitInfo"]的长度。注意,此处已经知道了该字段是数组,只是不知道其内容罢了(或不关注内容),那么可以直接用reflect.ValueOf求出长度,如下:

mylen:=reflect.ValueOf(data["splitInfo"]).Len()fmt.Println("splitInfolen:",mylen)

更多示例,待后续研究。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/Golang/5848.html