Подтвердить что ты не робот

Как получить размер памяти переменной?

Кто-нибудь знает, как получить размер памяти переменной (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
4b9b3361

Ответ 1

Для этого вы можете использовать функцию unsafe.Sizeof. Возвращает размер в байтах, занятый значением, которое вы передаете в него. Вот рабочий пример:

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. Т.е.: некоторые платформы могут не разрешать его использование.

Ответ 3

Размер переменной можно определить с помощью unsafe.Sizeof(a). Результат останется неизменным для данного типа (т.е. int, int64, string, struct и т.д.), Независимо от его значения. Однако для типа string вас может заинтересовать размер строки, которую ссылается переменной, и это определяется с помощью функции len(a) для данной строки. Следующий фрагмент иллюстрирует, что размер переменной строки типа всегда равен 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, возможно короткая форма для Integer для ASCII. Большинство программистов Golang, вероятно, неправильно понимают имя функции как Iota.

Ответ 4

От go/src/math/bits:

const uintSize = 32 << (^uint(0) >> 32 & 1) // 32 or 64

Я не тестировал его, но я ожидаю, что это будет быстрее, чем небезопасно. Sizeof().

BTW, так как член (^ uint (0) → 32 и 1) возвращает 0 на 32-битной дуге и 1 на 64-битной дуге, вы можете поместить любую мощность из двух значений слева от < оператор. Так что...

const uintSize = 4 << (^uint(0) >> 32 & 1) // 4 or 8

возвращает sizeof (uint) в байтах.

Ответ 5

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, если у вас нет особых причин использовать целочисленный тип без размера или без знака.