我正在编写将字节流反序列化为对象的代码,我一直在获取结构字段的指针。基本上代码的工作方式如下:它获取指向结构的指针,然后根据它序列化它的类型,例如。如果它是一个整数,它需要接下来的 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())
}
- 1 回答
- 0 关注
- 127 浏览
添加回答
举报
0/150
提交
取消