Go 1.18
With Go 1.18 you can use a generic function with unsafe.Sizeof:
func getSize[T any]() uintptr {
var v T
return unsafe.Sizeof(v)
}
Note that this will be more performant than using reflect, but it will introduce unsafe in your code base (some static analysis tools may give warns about that).
However if your goal is to improve code reuse or get sizes at run time (read on for the solution to that), this won't help much because you still need to call the function with proper instantiation:
type myType struct {
a int
b int64
c float32
d float64
e float64
}
func main() {
fmt.Println(getSize[myType]())
}
You might get the most out of this when used as part of some other type-parametrized code, e.g. a generic type or function where you pass a type param into getSize. A trivial example:
func printSize[T any](v T) {
// (doing something with v)
// instantiate with T and call
s := getSize[T]()
fmt.Println(s)
}
Otherwise you can always pass an actual argument. Then type inference will make it unnecessary to specify the type param. This code perhaps will be more flexible and allow you to pass arbitrary arguments at runtime, while keeping the benefits of avoiding reflection:
func getSize[T any](v T) uintptr {
return unsafe.Sizeof(v)
}
func main() {
type myType struct {
a int
b int64
c float32
d float64
e float64
}
info := myType{1, 2, 3.0, 4.0, 5.0}
// inferred type params
fmt.Println(getSize(info)) // 40
fmt.Println(getSize(5.0)) // 8
fmt.Println(getSize([]string{})) // 24
fmt.Println(getSize(struct {
id uint64
s *string
}{})) // 16
}
https://gotipplay.golang.org/p/kfhqYHUwB2S