関連記事
GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ · GitHub
概要
以下、自分用のメモです。ほぼ利用することは無いのですが、一応メモメモ。。。
最近になって、binary.NativeEndianという変数が encoding/binary パッケージに定義されていることを知りました。
ホストエンディアンがBigEndianなのかLittleEndianなのかを意識しなくて良いようになっているのですね。まあ、最近ホストエンディアンがBigEndianの環境に出会うことがほぼ無いので、利用することは稀かもしれませんが、こういうのって良いものです。
同じマシン内でプロセス間通信とかパイプでやり取りする際に使えそう。
試してみる
main.go
package binaryop import ( "bytes" "encoding/binary" "fmt" "math/rand/v2" "os" "unsafe" ) // NativeEndian は、binary.NativeEndian のサンプルです。 // // encoding/binary には、バイトオーダーを扱う3つの変数が定義されている。 // // - binary.BigEndian : 最上位バイトから順に格納(ネットワークバイトオーダーとも呼ばれる) // - binary.LittleEndian : 最下位バイトから順に格納(x86/x86-64系CPUの標準) // - binary.NativeEndian : 実行環境のCPUに合わせたバイトオーダー // // 昨今のデスクトップ・サーバー向けCPU(x86/x86-64)はリトルエンディアンが標準であり、 // ARMもiOS/Androidを含む多くの環境でリトルエンディアンモードで動作する。 // そのため、NativeEndianはほぼリトルエンディアンと同義になるケースが多い。 // // NativeEndianの主な用途は、ローカルIPC(共有メモリ・パイプ等)のように // 送受信が同一ホスト内で完結し、エンディアンを意識せずに記述したい場面で有用となる。 // ネットワーク通信ではBigEndian(ネットワークバイトオーダー)を明示するのが原則。 // // # REFERENCES // - https://pkg.go.dev/encoding/binary@go1.26.2#pkg-variables func NativeEndian() error { var ( v uint32 = 0x01020304 sz = int(unsafe.Sizeof(v)) be = make([]byte, sz) // big-endian le = make([]byte, sz) // little-endian ne = make([]byte, sz) // native-endian ) binary.BigEndian.PutUint32(be, v) binary.LittleEndian.PutUint32(le, v) binary.NativeEndian.PutUint32(ne, v) fmt.Printf("[Original ] 0x%08X\n", v) fmt.Printf("[Big Endian] %v\n", be) fmt.Printf("[Little Endian] %v\n", le) fmt.Printf("[Native Endian] %v\n", ne) fmt.Println("-----------------------") // // bianry.NativeEndianで読み取るサンプル // わざわざソケット用意するのは面倒なので os.Pipe() で代用 // var ( pr, pw *os.File err error ) if pr, pw, err = os.Pipe(); err != nil { return nil } // SEND SIDE type ( Header struct { Length uint32 } ) const ( charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" ) var ( // ランダム文字列生成 rnd = func(n int) []byte { b := make([]byte, n) for i := range b { b[i] = charset[rand.IntN(len(charset))] } return b } errCh = make(chan error, 1) ) defer close(errCh) go func() { defer pw.Close() var ( buf = new(bytes.Buffer) payload = rnd(10 + rand.IntN(21)) header = Header{Length: uint32(len(payload))} ) if err = binary.Write(buf, binary.NativeEndian, header); err != nil { errCh <- err return } if err = binary.Write(buf, binary.NativeEndian, payload); err != nil { errCh <- err return } if _, err = pw.Write(buf.Bytes()); err != nil { errCh <- err return } }() // RECV SIDE var ( header Header ) if err = binary.Read(pr, binary.NativeEndian, &header); err != nil { return err } var ( payload = make([]byte, header.Length) ) if err = binary.Read(pr, binary.NativeEndian, payload); err != nil { return err } fmt.Printf("length=%d, payload=%s\n", header.Length, payload) select { case err = <-errCh: return err default: } return nil }
実行結果
$ task task: [build] go build -o "/home/dev/dev/try-golang/try-golang" . task: [run] ./try-golang -onetime ENTER EXAMPLE NAME: binaryop_nativeendian [Name] "binaryop_nativeendian" [Original ] 0x01020304 [Big Endian] [1 2 3 4] [Little Endian] [4 3 2 1] [Native Endian] [4 3 2 1] ----------------------- length=29, payload=UX0ORrRx8FyzwPpnwkjE9fPqw3xOC [Elapsed] 888.021µs
参考情報
個人的Goのおすすめ書籍
個人的に読んでとても勉強になった書籍さんたちです。
過去の記事については、以下のページからご参照下さい。
サンプルコードは、以下の場所で公開しています。






