我有以下变量:
var foo int8
var bar [5]int8
我想计算两个变量中的字节数并输出总和 - 所以在这里它应该是1 + 5 = 6
。这可能吗?
答案 0 :(得分:2)
您可以使用reflect.Size
,由于某种原因会返回uintptr
,但实际上与unsafe.SizeOf
完全相同,而不必使用unsafe
。
var x [8]byte
t := reflect.TypeOf(x)
fmt.Println(t.Size())
障碍将是地图,切片,字符串和指针,您将获得标头/元数据的大小(或指针的指针大小)。如果那没关系,太好了!如果没有,你可以通过各种方式解决这个问题,这是我最好的选择:
func UnderlyingSize(x interface{}) uintptr {
v := reflect.ValueOf(x)
t := v.Type()
var size uintptr;
switch t.Kind() {
// For the builtin collections, we just multiply the len by the
// element size, for maps also do the key
case reflect.Map:
l := uintptr(v.Len())
size = t.Key().Size()*l + t.Elem().Size()*l
case reflect.Slice:
t := t.Elem();
size = t.Size() * uintptr(v.Len())
case reflect.Ptr:
t := t.Elem();
size = t.Size()
// Strings are just byte arrays, so it's just the len
case reflect.String:
size = uintptr(v.Len())
// For an interface, we need to find the underlying type
case reflect.Interface:
v := v.Elem()
size = UnderlyingSize(v)
// For anything else, including arrays, Size returns the correct value
default:
size = t.Size();
}
return size
}
使用Cap
而不是Len
会有争议,但它很容易改变自己。如果您想要标题信息的大小和基础大小,也可以将t.Size()
添加到这些值中的任何一个。请注意一个警告,即真正的map
可能需要更多的内存而不仅仅是键+值+标题大小,因为可能还有一些额外的信息。
如果你的数据结构是一个集合,你必须自己实现这样的东西,但如果它是一个简单的结构(即只由POD结构和内置类型组成),您只需添加所有成员的UnderlyingSize
即可。
答案 1 :(得分:1)
您可以使用unsafe.Sizeof(https://play.golang.org/p/FroasKud7I):
unsafe.Sizeof(foo) + unsafe.Sizeof(bar)