web-dev-qa-db-ja.com

変数のメモリサイズを取得する方法は?

誰でも変数のメモリサイズを取得する方法を知っていますか(intstring[]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
20

これには nsafe.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パッケージの場合と同じ制限が適用されます。つまり、一部のプラットフォームでは使用が許可されない場合があります。

34
jimt

unsafe.Sizeof() または reflect.Type.Size() のいずれかで実行できます

11
JimB

変数のサイズは、unsafe.Sizeof(a)を使用して決定できます。結果は、保持する値に関係なく、特定のタイプ(つまり、int、_int64_、stringstructなど)に対して同じままです。ただし、タイプ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)で実行できます。ここで、iint変数であり、関数によって返されるstringsに割り当てられます。

注:コンバーター関数の名前は Itoa であり、整数からASCIIへの短縮形である可能性があります。ほとんどのGolangプログラマーは、関数名をIotaと誤解する可能性があります。

4
Tapan Karecha

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を使用する必要があります。

0
Kelvin Kuo