私はGoを見ています。これは非常に有望に見えます。たとえば、go構造体のサイズを取得する方法を理解しようとしています。
type Coord3d struct {
X, Y, Z int64
}
もちろん24バイトであることは知っていますが、プログラムで知りたいのですが。
これを行う方法について何かアイデアはありますか?
import unsafe "unsafe"
/* Structure describing an inotify event. */
type INotifyInfo struct {
Wd int32 // Watch descriptor
Mask uint32 // Watch mask
Cookie uint32 // Cookie to synchronize two events
Len uint32 // Length (including NULs) of name
}
func doSomething() {
var info INotifyInfo
const infoSize = unsafe.Sizeof(info)
...
}
注: OPは間違っています。unsafe.Sizeofは、Coord3d構造体の例で24を返します。以下のコメントを参照してください。
Roger は、 unsafeパッケージのSizeOfメソッドの使用方法を既に示しました。関数によって返される値に依存する前に、必ずこれを読んでください。
サイズには、x によって参照される可能性のあるメモリは含まれません。たとえば、x がスライスの場合、Sizeof は、スライスが参照するメモリのサイズではなく、スライス記述子のサイズを返します。
これに加えて、いくつかの単純なルールを使用して構造体のサイズを簡単に計算する方法を説明したかったのです。そして、便利なサービスを使用して直感を検証する方法。
サイズは、それが構成する型と構造体のフィールドの順序によって異なります (異なるパディングが使用されるため)。これは、同じフィールドを持つ 2 つの構造体のサイズが異なる可能性があることを意味します。
たとえば、この構造体のサイズは 32 になります
struct {
a bool
b string
c bool
}
わずかな変更でサイズは 24になります(フィールドの順序がよりコンパクトになったため、25%の違いがあります)。
struct {
a bool
c bool
b string
}
写真からわかるように、2 番目の例では、パディングの 1 つを削除し、前のパディングを利用するためにフィールドを移動しました。アラインメントは、1、2、4、または 8 にすることができます。パディングは、アラインメントを埋めるために変数を埋めるために使用されたスペースです (基本的に無駄なスペース)。
このルールを知り、次のことを覚えておいてください。
[]bool
、[][][]string
同じです(最初に追加した引用を読み直すことを忘れないでください)n
。n
パディング、アラインメント、およびサイズ (バイト単位) の知識があれば、構造体を改善する方法をすぐに理解できます (ただし、サービスを使用して直感を検証することは理にかなっています)。
binary.TotalSize もオプションですが、unsafe.Sizeof: binary.TotalSize にはスライスの内容のサイズが含まれますが、unsafe.Sizeof は最上位の記述子のサイズのみを返します。TotalSize の使用例を次に示します。
package main
import (
"encoding/binary"
"fmt"
"reflect"
)
type T struct {
a uint32
b int8
}
func main() {
var t T
r := reflect.ValueOf(t)
s := binary.TotalSize(r)
fmt.Println(s)
}
バイナリパッケージを参照してください。具体的TotalSize
な方法は
これは変更される可能性がありますが、最後に確認したところ、構造のアラインメントに関連する未解決のコンパイラ バグ (bug260.go) があります。最終結果として、構造体をパックしても期待した結果が得られない可能性があります。これは、コンパイラ 6g バージョン 5383 リリース.2010-04-27 リリース用でした。結果には影響しないかもしれませんが、注意が必要です。
更新: リリース 2010-05-04 の時点で、go テスト スイートに残っている唯一のバグは、上記の bug260.go です。
布袋