doupao1978 2019-05-17 19:45
浏览 38
已采纳

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

I am attempting to generically get the size of any struct from an interface. This works fine with objects that are passed by value, but I can't figure out how to get the size of the object when it's passed the reference using an interface.

Here's an example indicating the problem I'm having: https://play.golang.org/p/QXXZm-j7_hZ

package main

import (
    "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)
}

This is the output:

expected size 50
valueObject size [8 12 50 12 0 0 0 0]
referenceObject size [8 12 4 12 12 12 12 8]

As you can see, I can get the size of the object when it's passed-by-value using reflect.TypeOf(valueObject).Size(), but nothing gives me the correct size when I pass-by-reference.

  • 写回答

1条回答 默认 最新

  • duangutian1426 2019-05-17 19:54
    关注

    There is no "reference" type in go, a pointer is a value like any other, and you can of course get the size of the pointer itself. You also are confusing the reflect.Value, the interface{} and the actual value you want the size of. Contributing to this confusion is that the package unsafe is special, and doesn't take an interface value, rather it can take any value directly, which is properly handled by the compiler.

    You could handle the pointer and the struct each with a separate call, or check whether you have a pointer and call Elem():

    // struct
    reflect.ValueOf(i).Type().Size()
    // pointer
    reflect.ValueOf(i).Elem().Type().Size()
    

    However, since optionally dereferencing a pointer is quite common, you can use reflect.Indirect to handle both types at once:

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

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

    For reference, a description of what some the attempts are actually taking:

    // 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())),
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 GDI处理通道视频时总是带有白色锯齿
  • ¥20 用雷电模拟器安装百达屋apk一直闪退
  • ¥15 算能科技20240506咨询(拒绝大模型回答)
  • ¥15 自适应 AR 模型 参数估计Matlab程序
  • ¥100 角动量包络面如何用MATLAB绘制
  • ¥15 merge函数占用内存过大
  • ¥15 Revit2020下载问题
  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大
  • ¥15 单片机无法进入HAL_TIM_PWM_PulseFinishedCallback回调函数