如何在Go中获取包含数据结构的结构的大小?

如何在Go中获取包含数据结构的结构的大小?,go,reflection,go-reflect,Go,Reflection,Go Reflect,我目前正在尝试获取Go中复杂结构的大小 我读过使用反射和不安全的解决方案,但这两种解决方案都不适用于包含数组或映射(或指向底层数据结构的任何其他字段)的结构 例如: type testStruct struct { A int B string C struct{} items map[string]string } 如果items中包含一些值,我如何找出上面的正确字节大小?使用包reflect,可以非常接近结构及其内容所需的内存量。您需

我目前正在尝试获取Go中复杂结构的大小

我读过使用
反射
不安全
的解决方案,但这两种解决方案都不适用于包含数组或映射(或指向底层数据结构的任何其他字段)的结构

例如:

type testStruct struct {
    A     int
    B     string
    C     struct{}
    items map[string]string
}

如果
items
中包含一些值,我如何找出上面的正确字节大小?

使用包reflect,可以非常接近结构及其内容所需的内存量。您需要遍历字段并获得每个字段的大小。例如:

func getSize(v interface{}) int {
    size := int(reflect.TypeOf(v).Size())
    switch reflect.TypeOf(v).Kind() {
    case reflect.Slice:
        s := reflect.ValueOf(v)
        for i := 0; i < s.Len(); i++ {
            size += getSize(s.Index(i).Interface())
        }
    case reflect.Map:
        s := reflect.ValueOf(v)
        keys := s.MapKeys()
        size += int(float64(len(keys)) * 10.79) // approximation from https://golang.org/src/runtime/hashmap.go
        for i := range(keys) {
            size += getSize(keys[i].Interface()) + getSize(s.MapIndex(keys[i]).Interface())
        }
    case reflect.String:
        size += reflect.ValueOf(v).Len()
    case reflect.Struct:
        s := reflect.ValueOf(v)
        for i := 0; i < s.NumField(); i++ {
            if s.Field(i).CanInterface() {
                size += getSize(s.Field(i).Interface())
            }
        }
    }
    return size
}
func getSize(v接口{})int{
size:=int(reflect.TypeOf(v).size())
开关反射.TypeOf(v).Kind(){
case reflect.Slice:
s:=反射值(v)
对于i:=0;i
这将使用reflect获得v的大小,然后,对于本例中支持的类型(切片、映射、字符串和结构),它将计算存储在这些类型中的内容所需的内存。您需要在此处添加需要支持的其他类型

有几个细节需要解决:

  • 私有字段不计算在内
  • 对于结构,我们重复计算基本类型

  • 第二,在处理结构时,您可以在执行递归调用之前过滤掉它们,您可以检查文档中的类型。

    项中的值的数量不会改变
    testStruct
    值的大小。您也没有得到映射结构本身的大小。您是对的!我添加了一个基于伟大解决方案的近似值,我感谢您列出您的方法的缺点。非常感谢!