memory-management go runtime

memory management - ¿Cómo obtener el tamaño de memoria de la variable?



memory-management go (4)

¿Alguien sabe cómo obtener el tamaño de memoria de la variable ( int , string , []struct , etc) e imprimirlo? ¿Es posible?

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


El tamaño de una variable se puede determinar utilizando unsafe.Sizeof(a) . El resultado seguirá siendo el mismo para un tipo dado (es decir, int , int64 , string , struct , etc.), independientemente del valor que tenga. Sin embargo, para la string tipo, puede interesarle el tamaño de la cadena a la que hace referencia la variable, y esto se determina mediante el uso de la función len(a) en una cadena determinada. El siguiente fragmento de código muestra que el tamaño de una variable de tipo cadena siempre es 8, pero la longitud de una cadena a la que pueden hacer referencia las variables:

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)) }

Salida:

s1 size: string, 8 s2 size: string, 8 s1 len: string, 3 s2 len: string, 6

La última parte de su pregunta es sobre la asignación de la longitud (es decir, un valor int ) a una string . Esto se puede hacer mediante s := strconv.Itoa(i) donde i es una variable int y la string devuelta por la función se asigna a s .

Nota: el nombre de la función de conversión es Itoa , posiblemente una forma abreviada de Integer a ASCII. Es probable que la mayoría de los programadores de Golang interpreten erróneamente el nombre de la función como Iota .



Puede utilizar la función unsafe.Sizeof para esto. Devuelve el tamaño en bytes, ocupado por el valor que se le pasa. Aquí hay un ejemplo de trabajo :

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)) }

Tenga en cuenta que algunas plataformas prohíben explícitamente el uso de inseguro, porque es ... bueno, inseguro. Esto solía incluir AppEngine. No estoy seguro si ese es el caso hoy, pero me imagino que sí.

Como observa @Timur Fayzrakhmanov, reflect.TypeOf(variable).Size() le dará la misma información. Para el paquete reflect , la misma restricción se unsafe paquete unsafe . Es decir: algunas plataformas pueden no permitir su uso.


unsafe.Sizeof () es la solución correcta.

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))

Los tipos int, uint y uintptr suelen tener 32 bits de ancho en sistemas de 32 bits y 64 bits de ancho en sistemas de 64 bits. Cuando necesite un valor entero, debe usar int a menos que tenga una razón específica para usar un tipo de entero con tamaño o sin signo.