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

从指针接口获取结构的大小

从指针接口获取结构的大小

Go
12345678_0001 2023-06-19 15:30:39
我正在尝试从接口中一般获取任何结构的大小。这适用于按值传递的对象,但我不知道如何在使用接口传递引用时获取对象的大小。这是一个说明我遇到的问题的示例: https://play.golang.org/p/QXXZm-j7_hZpackage mainimport (    "fmt"    "reflect"    "unsafe")type T struct {    c [50]byte}func main() {    fmt.Println("Hello, playground")    var t T    s := unsafe.Sizeof(t)    fmt.Println("expected size", s)    getSize(t, &t)}func getSize(valueObject interface{}, referenceObject interface{}) {    vs := []uintptr{        unsafe.Sizeof(valueObject),        unsafe.Sizeof(reflect.ValueOf(valueObject)),        reflect.TypeOf(valueObject).Size(), // THIS WORKS FOR VALUE        reflect.TypeOf(reflect.ValueOf(valueObject)).Size(),        0, //reflect.TypeOf(reflect.ValueOf(valueObject).Elem()).Size(), //EXCEPTION ACCESSING ELEM WITH VALUE        0, //reflect.TypeOf(reflect.ValueOf(valueObject).Elem()).Size(), //EXCEPTION ACCESSING ELEM WITH VALUE        0, //unsafe.Sizeof(reflect.ValueOf(valueObject).Elem()), //EXCEPTION ACCESSING ELEM WITH VALUE        0, //unsafe.Sizeof(reflect.TypeOf(reflect.ValueOf(valueObject).Elem())), //EXCEPTION ACCESSING ELEM WITH VALUE    }    fmt.Println("valueObject size", vs)    rs := []uintptr{        unsafe.Sizeof(referenceObject),        unsafe.Sizeof(reflect.ValueOf(referenceObject)),        reflect.TypeOf(referenceObject).Size(),        reflect.TypeOf(reflect.ValueOf(referenceObject)).Size(),        reflect.TypeOf(reflect.ValueOf(referenceObject).Elem()).Size(),        reflect.TypeOf(reflect.ValueOf(referenceObject).Elem()).Size(),        unsafe.Sizeof(reflect.ValueOf(referenceObject).Elem()),        unsafe.Sizeof(reflect.TypeOf(reflect.ValueOf(referenceObject).Elem())),    }    fmt.Println("referenceObject size", rs)}这是输出:expected size 50valueObject size [8 12 50 12 0 0 0 0]referenceObject size [8 12 4 12 12 12 12 8]正如您所看到的,当我使用 传递值时,我可以获得对象的大小reflect.TypeOf(valueObject).Size(),但是当我传递引用时,没有任何东西给我正确的大小。
查看完整描述

1 回答

?
翻阅古今

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

go 中没有“引用”类型,指针和其他任何东西一样都是一个值,你当然可以得到指针本身的大小。您还混淆了您想要的大小的reflect.Value、 theinterface{}和实际值。导致这种混淆的原因是包unsafe是特殊的,它不接受接口值,而是可以直接接受任何值,这由编译器正确处理。


您可以通过单独的调用处理指针和结构,或者检查您是否有指针并调用Elem():


// struct

reflect.ValueOf(i).Type().Size()

// pointer

reflect.ValueOf(i).Elem().Type().Size()

但是,由于可选地取消引用指针是很常见的,您可以使用reflect.Indirect一次处理这两种类型:


reflect.Indirect(reflect.ValueOf(i)).Type().Size()

https://play.golang.org/p/og-uMDXCmEr


作为参考,一些尝试实际采取的描述:


// size of the interface value

unsafe.Sizeof(valueObject)


// size of reflect.Value

unsafe.Sizeof(reflect.ValueOf(valueObject))


// size of the reflect.Value type 

reflect.TypeOf(reflect.ValueOf(valueObject)).Size()


// size of the interface value

unsafe.Sizeof(referenceObject)


// size of the reflect.Value

unsafe.Sizeof(reflect.ValueOf(referenceObject))


// size of the pointer value

reflect.TypeOf(referenceObject).Size()


// size of the reflect.Value type

reflect.TypeOf(reflect.ValueOf(referenceObject)).Size(),


// size of the of reflect.Value type again

reflect.TypeOf(reflect.ValueOf(referenceObject).Elem()).Size()


// size of the reflect.Value

unsafe.Sizeof(reflect.ValueOf(referenceObject).Elem()),


// size of the reflect.Type interface value

unsafe.Sizeof(reflect.TypeOf(reflect.ValueOf(referenceObject).Elem())),


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

添加回答

举报

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