Golong使用反射提取数组中的数组对象、reflect.Value类型到string类型的转换
首先json数据为下:
{ "code": 200, "data": { "pcode": "1000", "annList": ["java.util.ArrayList", [{ "Name": "no1", "sex": "1" }, { "Name": "n02", "@sex": "2" }]] } }
目的:在JSON提取出来“data”中“annList”数组的第二个参数,该参数是个数组对象
第一步:主函数如下:
func main() { str :=`{"code":200,"data":{"pcode":"1000","annList":["java.util.ArrayList",[{"Name":"no1","sex":"1"},{"Name":"n02","@sex":"2"}]]}}` result, _ :=GetArrayByFanshe([]byte(str)) fmt.Println(string(result)) }
第二步:GetArrayByFanshe函数接收main函数参数,提取数据
代码块一:
data := string(body) fmt.Println("接收到的参数信息data为:",data) fmt.Printf("变量data的数据类型是:%T\n",data) olderResult := make(map[string]interface{}) err := json.Unmarshal([]byte(data), &olderResult) if err != nil { fmt.Printf("Json转换失败") return nil, err } fmt.Println("经过json.Unmarshal函数处理后,数据olderResult为:",olderResult) fmt.Printf("变量olderResult的数据类型是:%T\n",olderResult) //NewResult作为参数 newResult := make(map[string]interface{}) newResult["code"] = olderResult["code"] //获取date中的数组对象 resData := olderResult["data"] fmt.Println("olderResult类型为map,提取key为data的value值赋值给resData,数据resData为:",resData)
结果如下:
代码块二:
//提取data中的annList //resAnnexList := resData["annList"] resAnnexList := resData.(map[string]interface{})["annList"] //提取resAnnexList第二个值 var resList interface{} fmt.Println("resAnnexList为:",resAnnexList) fmt.Printf("resAnnexList的数据类型是:%T\n",resAnnexList)
结果如下:
代码块第二行错误写法:
resAnnexList := resData["annList"]
此写法提取map参数会发现以下错误:
此处报错:resData类型为 interface{},需要我们把resData断言强转为map类型
改为代码块第三行正确写法:
resAnnexList := resData.(map[string]interface{})["annList"]
代码块三(转成数组切片提取数据):
res := resAnnexList.([]interface{})[1:] newResult["data"] = res fmt.Println("resAnnexList转成数组,切片提取数据赋值给res",res) fmt.Println("newResult的值为",newResult)
代码块四(反射提取数据):
fmt.Println("reflect.TypeOf(resAnnexList)=",reflect.TypeOf(resAnnexList)) //TypeOf返回接口中保存的值的类型, fmt.Println("reflect.TypeOf(resAnnexList).Kind()=",reflect.TypeOf(resAnnexList).Kind()) //Kind返回该接口的具体分类 switch reflect.TypeOf(resAnnexList).Kind() { //此处等于 switch slice case reflect.Slice: s := reflect.ValueOf(resAnnexList) //返回s持有值的第i个元素 resList = s.Index(1) //list := s.Index(1) //rlist := list.Interface() //re := rlist.([]interface{}) //resList = re } newResult["data"] = resList fmt.Println("resList的值为",resList) fmt.Printf("resList类型%T为\n",resList) fmt.Println("newResult的值为",newResult)
由此可见:反射获取到的值是reflect.Value类型的,不能直接使用
解决方法:通过反射变量的Interface()方法转成Interface{}类型,再把Interface{}类型通过断言转成想要的类型
switch reflect.TypeOf(resAnnexList).Kind() { //此处等于 switch slice case reflect.Slice: s := reflect.ValueOf(resAnnexList) //返回s持有值的第i个元素 //resList = s.Index(1) list := s.Index(1) rlist := list.Interface() re := rlist.([]interface{}) resList = re } newResult["data"] = resList fmt.Println("resList的值为",resList) fmt.Printf("resList类型%T为\n",resList) fmt.Println("newResult的值为",newResult)
代码块五:所有代码
package main import ( "encoding/json" "fmt" "reflect" ) func GetArrayByFanshe(body []byte) ([]byte, error) { data := string(body) fmt.Println("接收到的参数信息data为:",data) fmt.Printf("变量data的数据类型是:%T\n",data) olderResult := make(map[string]interface{}) err := json.Unmarshal([]byte(data), &olderResult) if err != nil { fmt.Printf("Json转换失败") return nil, err } fmt.Println("经过json.Unmarshal函数处理后,数据olderResult为:",olderResult) fmt.Printf("变量olderResult的数据类型是:%T\n",olderResult) //NewResult作为参数 newResult := make(map[string]interface{}) newResult["code"] = olderResult["code"] //获取date中的数组对象 resData := olderResult["data"] fmt.Println("olderResult类型为map,提取key为data的value值赋值给resData,数据resData为:",resData) //提取data中的annList //resAnnexList := resData["annList"] resAnnexList := resData.(map[string]interface{})["annList"] //提取resAnnexList第二个值 var resList interface{} fmt.Println("resAnnexList为:",resAnnexList) fmt.Printf("resAnnexList的数据类型是:%T\n",resAnnexList) res := resAnnexList.([]interface{})[1:] fmt.Println("resAnnexList转成数组,切片提取数据赋值给res",res) fmt.Println("reflect.TypeOf(resAnnexList)=",reflect.TypeOf(resAnnexList)) //TypeOf返回接口中保存的值的类型,TypeOf(nil)会返回nil。 fmt.Println("reflect.TypeOf(resAnnexList).Kind()=",reflect.TypeOf(resAnnexList).Kind()) //Kind返回该接口的具体分类,此处返回slice switch reflect.TypeOf(resAnnexList).Kind() { //此处等于 switch slice case reflect.Slice: s := reflect.ValueOf(resAnnexList) //返回s持有值的第i个元素 //resList = s.Index(1) list := s.Index(1) rlist := list.Interface() re := rlist.([]interface{}) resList = re } newResult["data"] = resList fmt.Println("resList的值为",resList) fmt.Printf("resList类型%T为\n",resList) fmt.Println("newResult的值为",newResult) //转换成json格式 resultData, err := json.Marshal(newResult) if err != nil { fmt.Printf("Json转换失败") return nil, err } return resultData, nil } func main() { str :=`{"code":200,"data":{"pcode":"1000","annList":["java.util.ArrayList",[{"Name":"no1","sex":"1"},{"Name":"n02","@sex":"2"}]]}}` result, _ :=GetArrayByFanshe([]byte(str)) fmt.Println(string(result)) }