英文:
Getting size of a structure in GAE/Go
问题
我想要获取GAE/Go中结构体的大小。
我阅读了这篇帖子,并编写了以下代码。
import (
"reflect"
"unsafe"
)
func GetSize(T interface{}) {
size := reflect.TypeOf(T).Size()
return int((*int)(unsafe.Pointer(size)))
}
但是这段代码无法工作,因为GAE不允许导入unsafe
包。
在GAE/Go中,我该如何实现这个功能呢?
英文:
I would like to get the size of a structure in GAE/Go.
I read this post and wrote the code as below.
import (
"reflect"
"unsafe"
)
func GetSize(T interface{}) {
size := reflect.TypeOf(T).Size()
return int((*int)(unsafe.Pointer(size)))
}
But this code does not work because GAE does not allow to import unsafe
.
How can I do this in GAE/Go?
答案1
得分: 2
你提出的解决方案不是有效的代码,它有多个错误。
例如,GetSize()
没有结果类型,所以你无法返回任何内容。
接下来,你返回的表达式也是语法错误,它试图将*int
指针转换为无效的int
类型。
你需要先解引用指针,所以正确的语法应该是:
func GetSize(T interface{}) int {
size := reflect.TypeOf(T).Size()
return int(*(*int)(unsafe.Pointer(size)))
}
但是,这没有意义。reflect.Type.Size()
已经返回了大小(存储给定类型的值所需的字节数),所以没有必要使用unsafe
的魔法。可能令人困惑的是,它的返回类型是uintptr
,但你可以将其转换为int
后直接使用该值。
简单地使用:
func GetSize(v interface{}) int {
return int(reflect.TypeOf(v).Size())
}
进行测试:
fmt.Println("Size of int:", GetSize(int(0)))
fmt.Println("Size of int64:", GetSize(int64(0)))
fmt.Println("Size of [100]byte:", GetSize([100]byte{}))
输出结果(在Go Playground上尝试):
Size of int: 4
Size of int64: 8
Size of [100]byte: 100
有一件事你不能忘记:这个GetSize()
函数不会递归地检查传入值的大小。所以,例如,如果它是一个具有指针字段的结构体,它不会“计算”指向值的大小,只会计算指针字段的大小。
构建一个能够递归计算复杂数据结构总大小的GetSize()
函数并不容易,因为存在像map
这样的类型。有关详细信息,请参见https://stackoverflow.com/questions/44257522/how-to-get-variable-memory-size-of-variable-in-golang/44258164#44258164
英文:
Your proposed solution is not valid code, it has multiple errors.
For example GetSize()
has no result type, so you couldn't return anything.
Next, the expression you return is also a syntax error, it attempts to convert an *int
pointer to int
which is not valid.
You need to dereference the pointer first, so the correct syntax would be:
func GetSize(T interface{}) int {
size := reflect.TypeOf(T).Size()
return int(*(*int)(unsafe.Pointer(size)))
}
But. It makes no sense. reflect.Type.Size()
already returns the size (the number of bytes needed to store a value of the given type), so there is no need of that unsafe
magic. What may be confusing is that its return type is uintptr
, but you may simply use that value after converting it to int
for example.
Simply use:
func GetSize(v interface{}) int {
return int(reflect.TypeOf(v).Size())
}
Testing it:
fmt.Println("Size of int:", GetSize(int(0)))
fmt.Println("Size of int64:", GetSize(int64(0)))
fmt.Println("Size of [100]byte:", GetSize([100]byte{}))
Output (try it on the Go Playground):
Size of int: 4
Size of int64: 8
Size of [100]byte: 100
One thing you must not forget: this GetSize()
will not recurisvely examine the size of the passed value. So for example if it's a struct with a pointer field, it will not "count" the size of the pointed value, only the size of the pointer field.
Constructing a GetSize()
that recurisvely counts the total size of a complex data structure is non-trivial due to types like map
. For details, see https://stackoverflow.com/questions/44257522/how-to-get-variable-memory-size-of-variable-in-golang/44258164#44258164
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论