如何在 Go 中获取包含数据结构的结构的大小?
How to get size of struct containing data structures in Go?
我目前正在尝试获取 Go 中复杂结构的大小。
我读过使用 reflect
和 unsafe
的解决方案,但这些都没有帮助包含数组或映射的结构(或任何其他指向底层数据结构的字段) .
示例:
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
}
这会使用 reflect 获取 v 的大小,然后,对于本示例中支持的类型(切片、映射、字符串和结构),它会计算存储在其中的内容所需的内存。您需要在此处添加您需要支持的其他类型。
有几个细节需要解决:
- 私有字段不计算在内。
- 对于结构,我们重复计算基本类型。
对于第二个,你可以在处理结构时在进行递归调用之前过滤掉它们,你可以在reflect package.
的文档中查看种类
我目前正在尝试获取 Go 中复杂结构的大小。
我读过使用 reflect
和 unsafe
的解决方案,但这些都没有帮助包含数组或映射的结构(或任何其他指向底层数据结构的字段) .
示例:
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
}
这会使用 reflect 获取 v 的大小,然后,对于本示例中支持的类型(切片、映射、字符串和结构),它会计算存储在其中的内容所需的内存。您需要在此处添加您需要支持的其他类型。
有几个细节需要解决:
- 私有字段不计算在内。
- 对于结构,我们重复计算基本类型。
对于第二个,你可以在处理结构时在进行递归调用之前过滤掉它们,你可以在reflect package.
的文档中查看种类