Go conversion between struct and byte array

Shriganesh Shintre picture Shriganesh Shintre · Oct 15, 2014 · Viewed 20k times · Source

I am writing a client - server application in Go. I want to perform C-like type casting in Go.

E.g. in Go

type packet struct {
    opcode uint16
    data [1024]byte
}

var pkt1 packet
...
n, raddr, err := conn.ReadFromUDP(pkt1)  // error here

Also I want to perform C-like memcpy(), which will allow me to directly map the network byte stream received to a struct.

e.g. with above received pkt1

type file_info struct {
    file_size uint32       // 4 bytes
    file_name [1020]byte
}

var file file_info
if (pkt1.opcode == WRITE) {
    memcpy(&file, pkt1.data, 1024)
}

Answer

Ainar-G picture Ainar-G · Oct 15, 2014

unsafe.Pointer is, well, unsafe, and you don't actually need it here. Use encoding/binary package instead:

// Create a struct and write it.
t := T{A: 0xEEFFEEFF, B: 3.14}
buf := &bytes.Buffer{}
err := binary.Write(buf, binary.BigEndian, t)
if err != nil {
    panic(err)
}
fmt.Println(buf.Bytes())

// Read into an empty struct.
t = T{}
err = binary.Read(buf, binary.BigEndian, &t)
if err != nil {
    panic(err)
}
fmt.Printf("%x %f", t.A, t.B)

Playground

As you can see, it handles sizes and endianness quite neatly.