为了账号安全,请及时绑定邮箱和手机立即绑定

如何通过在 GO 中反映来获取结构字段的地址

如何通过在 GO 中反映来获取结构字段的地址

Go
千巷猫影 2023-06-05 17:23:48
我正在编写将字节流反序列化为对象的代码,我一直在获取结构字段的指针。基本上代码的工作方式如下:它获取指向结构的指针,然后根据它序列化它的类型,例如。如果它是一个整数,它需要接下来的 4 个字节。棘手的情况是,如果它是一个结构,因为我必须对其所有属性递归运行反序列化,而且我不知道如何获取其字段的地址以将它们传递给反序列化。func Deserialize(objPtr interface{}, b []byte) (bytesRead int) {    // it should be the address of the object    val := reflect.ValueOf(objPtr).Elem()    valPtr := reflect.ValueOf(objPtr)    // check if either the object or *object is Serializable    _, isSerializable := (val.Interface()).(Serializable)    _, bo := (valPtr.Interface()).(Serializable)    isSerializable = isSerializable || bo    // specific type serialization    if isSerializable{        return objPtr.(Serializable).Deserializebyte(b)    }    switch val.Kind() {    case reflect.Uint32, reflect.Int, reflect.Int32:        res := reflect.ValueOf(binary.LittleEndian.Uint32(b[:4]))        valPtr.Set(res)        return 4    case reflect.Uint64, reflect.Int64:        res := reflect.ValueOf(binary.LittleEndian.Uint32(b[:8]))        valPtr.Set(res)        return 8    case reflect.Struct:        n_bytes := 0        for i := 0; i < val.NumField(); i++ {            // stuck in here            valPtr.Elem()            // I don't think the next line works            last_n_bytes := Deserialize(&(valPtr.Elem().Field(i).Interface()), b)            n_bytes += last_n_bytes            b = b[last_n_bytes:]        }        //valPtr.Set(res)        return n_bytes    default:        panic("this panic is for debug, every case should be handled above")        res := val.Bytes()        valPtr.Set(res)        return len(val.Bytes())    }    return 0}
查看完整描述

1 回答

?
梦里花落0921

TA贡献1772条经验 获得超5个赞

使用 reflect API 获取字段的地址:

last_n_bytes := Deserialize(valPtr.Elem().Field(i).Addr().Interface(), b)

superint示例发生错误,因为应用程序通过反射 API 获取了未导出字段的地址。这是不允许的,因为它会允许另一个包修改该字段。

这是一个导出字段的工作示例:

type superint struct {

    A int

    B int

}


func (s *superint) lol() {}


type a interface{ lol() }


func main() {

    i := superint{A: 1, B: 9}

    valPtr := reflect.ValueOf(&i)

    fmt.Printf("%v \n", &i.A)

    fmt.Printf("%v \n", valPtr.Elem().Field(0).Addr().Interface())

}


查看完整回答
反对 回复 2023-06-05
  • 1 回答
  • 0 关注
  • 127 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信