有人知道如何获取变量(int
,string
,[]struct
等)的内存大小并打印出来吗?有可能吗?
var i int = 1
//I want to get something like this:
fmt.Println("Size of i is: %?", i)
//Also, it would be nice if I could store the value into a string
答案 0 :(得分:33)
您可以使用unsafe.Sizeof功能。 它返回以字节为单位的大小,由传递给它的值占用。 这是a working example:
package main
import "fmt"
import "unsafe"
func main() {
a := int(123)
b := int64(123)
c := "foo"
d := struct {
FieldA float32
FieldB string
}{0, "bar"}
fmt.Printf("a: %T, %d\n", a, unsafe.Sizeof(a))
fmt.Printf("b: %T, %d\n", b, unsafe.Sizeof(b))
fmt.Printf("c: %T, %d\n", c, unsafe.Sizeof(c))
fmt.Printf("d: %T, %d\n", d, unsafe.Sizeof(d))
}
请注意,某些平台明确禁止使用不安全的,因为它是......好吧,不安全。这曾经包括AppEngine。不确定今天是否仍然如此,但我想是这样。
正如@Timur Fayzrakhmanov所说,reflect.TypeOf(variable).Size()
会给你相同的信息。对于reflect
包,与unsafe
包的限制相同。即:某些平台可能不允许使用它。
答案 1 :(得分:11)
答案 2 :(得分:4)
可以使用unsafe.Sizeof(a)
确定变量的大小。对于给定类型(即int
,int64
,string
,struct
等),结果将保持不变,无论其值如何。但是,对于类型string
,您可能对变量引用的字符串的大小感兴趣,这是通过对给定字符串使用len(a)
函数来确定的。以下代码段说明了string类型变量的大小始终为8,但变量引用的字符串长度可能会有所不同:
package main
import "fmt"
import "unsafe"
func main() {
s1 := "foo"
s2 := "foobar"
fmt.Printf("s1 size: %T, %d\n", s1, unsafe.Sizeof(s1))
fmt.Printf("s2 size: %T, %d\n", s2, unsafe.Sizeof(s2))
fmt.Printf("s1 len: %T, %d\n", s1, len(s1))
fmt.Printf("s2 len: %T, %d\n", s2, len(s2))
}
输出:
s1 size: string, 8
s2 size: string, 8
s1 len: string, 3
s2 len: string, 6
问题的最后一部分是将长度(即int
值)分配给string
。这可以通过s := strconv.Itoa(i)
完成,其中i
是int
变量,并且该函数返回的string
已分配给s
。
注意:转换器函数的名称是Itoa
,可能是整数到ASCII的简写形式。大多数Golang程序员可能会将函数名称误读为Iota
。
答案 3 :(得分:1)
我编写了一个程序包,用于计算运行时变量消耗的实际内存大小:https://github.com/DmitriyVTitov/size 它具有单一功能,因此基本用法是:
fmt.Println(size.Of(varName))
答案 4 :(得分:0)
unsafe.Sizeof()是正确的解决方案。
var i int
var u uint
var up uintptr
fmt.Printf("i Type:%T Size:%d\n", i, unsafe.Sizeof(i))
fmt.Printf("u Type:%T Size:%d\n", u, unsafe.Sizeof(u))
fmt.Printf("up Type:%T Size:%d\n", up, unsafe.Sizeof(up))
int,uint和uintptr类型在32位系统上通常为32位宽,在64位系统上为64位宽。当你需要一个整数值时,你应该使用int,除非你有特定的理由使用大小或无符号整数类型。