首先,结构体里不要有指向上一层的指针,否则会循环读取直至崩溃,后面会把这个问题修掉。仅限测试使用
下面上源代码
package sizestruct
import (
"fmt"
"reflect"
"unsafe"
)
func SizeStruct(data interface{}) int {
return sizeof(reflect.ValueOf(data))
}
func sizeof(v reflect.Value) int {
switch v.Kind() {
case reflect.Map:
sum := 0
keys := v.MapKeys()
for i := 0; i < len(keys); i++ {
mapkey := keys[i]
s := sizeof(mapkey)
if s < 0 {
return -1
}
sum += s
s = sizeof(v.MapIndex(mapkey))
if s < 0 {
return -1
}
sum += s
}
return sum
case reflect.Slice, reflect.Array:
sum := 0
for i, n := 0, v.Len(); i < n; i++ {
s := sizeof(v.Index(i))
if s < 0 {
return -1
}
sum += s
}
return sum
case reflect.String:
sum := 0
for i, n := 0, v.Len(); i < n; i++ {
s := sizeof(v.Index(i))
if s < 0 {
return -1
}
sum += s
}
return sum
case reflect.Ptr, reflect.Interface:
p := (*[]byte)(unsafe.Pointer(v.Pointer()))
if p == nil {
return 0
}
return sizeof(v.Elem())
case reflect.Struct:
sum := 0
for i, n := 0, v.NumField(); i < n; i++ {
s := sizeof(v.Field(i))
if s < 0 {
return -1
}
sum += s
}
return sum
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128,
reflect.Int:
return int(v.Type().Size())
default:
fmt.Println("t.Kind() no found:", v.Kind())
}
return -1
}