go interface 转 string_golang pb转map

今天遇到一个问题,想把pb转成map,如下所示:

func TestUnmarshalPbTojson(t *testing.T)  {
   rq:=&UserInfo{Status: "error",Amount: "1.11"}
   //m:=map[string]interface{}{}
   err:=json.Valid([]byte(rq.String()))  //not valid,不能够直接由该字符串转成map
   t.Errorf("err:%v,json str:%v",err,rq.String())
}

所以很无奈,就不得不选择了稍微繁琐一点的方式(使用go的反射获得pb结构体的field,使用for循环将field转成map),如下代码所示:

func TestUnmarshalPbTojson(t *testing.T)  {
   rq:=&userInfo{Status: "error",Amount: "1.11"}
   //m:=map[string]interface{}{}
   err:=json.Valid([]byte(rq.String()))
   t.Errorf("err:%v,json str:%v",err,rq.String())
   pb2map(rq,t)
}
func pb2map(rp interface{}, t *testing.T) {
 m:=make(map[string]string)
 vals:=reflect.ValueOf(rp).Elem()
 for i:=0;i<vals.NumField();i++{
  valueField:=vals.Field(i)
  typeField:=vals.Type().Field(i)

  
  f:=valueField.Interface()
  val:=reflect.ValueOf(f)  //由于遍历的时候,会遍历到私有变量,但私有变量的值不可以直接取得,会报pa
  m[typeField.Name]=val.String()
 }
 t.Logf("pb2map,origin:%v,dst:%v",rp,vals)
}

因为私有变量不可以直接使用反射获取到内部的value,不得不进一步查询相关api,最后发现了Value.CanInterface(),通过调用这个方法,go会内部校验该变量是否为私有变量,是否可被导出,从而成功解决了我的问题,最终代码如下所示:

func pb2map(rp interface{}, t *testing.T) {
   m:=make(map[string]string)
   vals:=reflect.ValueOf(rp).Elem()
   for i:=0;i<vals.NumField();i++{
      valueField:=vals.Field(i)
      typeField:=vals.Type().Field(i)

      if valueField.CanInterface(){
         f:=valueField.Interface()
         val:=reflect.ValueOf(f)
         t.Logf("pb2map,name:%v,val:%v,tagname:%v",typeField.Name,val.String(),typeField.Tag.Get("json"))
         m[typeField.Tag.Get("json")]=val.String() //可以根据需要取具体的tag,做相应的处理即可
      }
   }
   t.Logf("pb2map,origin:%v,dst:%v",rp,vals)
}

也算是比较好的一天吧,解决了问题,也新学了api的使用,也算是对go的理解更加加深了吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值