Using binary.ByteOrder
The encoding/binary
package makes it easy, values of the binary.ByteOrder
interface type can be used to read uint32
values from byte slices. There is a binary.LittleEndian
exported variable which you can use out of the box. Put this in a simple for
loop to read all 8 values:
data := [32]byte{1, 0, 0, 0, 2}
ints := [8]uint32{}
for i := 0; i < len(data); i += 4 {
ints[i/4] = binary.LittleEndian.Uint32(data[i:])
}
fmt.Println(ints)
Output (try it on the Go Playground):
[1 2 0 0 0 0 0 0]
And this of course works for any number of bytes (being multiple of 4), not just for 32.
Using binary.Read()
Another, even shorter alternative would be to use binary.Read()
:
func Read(r io.Reader, order ByteOrder, data interface{}) error
This of course requires an io.Reader
, for which you may use bytes.NewBuffer()
. This way the conversion is a simple line:
data := [32]byte{1, 0, 0, 0, 2}
ints := [8]uint32{}
err := binary.Read(bytes.NewBuffer(data[:]), binary.LittleEndian, &ints)
fmt.Println(ints, err)
Output (try it on the Go Playground):
[1 2 0 0 0 0 0 0] <nil>
Using unsafe.Pointer
For completeness, here's yet another, unsafe way. Since arrays are laid out sequentially in memory, both arrays occupy the same size. We can interpret the memory area of the input as a value of the output type:
data := [32]byte{1, 0, 0, 0, 2}
ints := [8]uint32{}
ints = *(*[8]uint32)((unsafe.Pointer)(&data))
fmt.Println(ints)
Output (try it on the Go Playground):
[1 2 0 0 0 0 0 0]
This is the most efficient and the most unsafe way to solve your task.
In this case it's safe to do it like presented, but use package unsafe
with caution and as a last resort. Many other, seemingly very similar cases might not work. We were "lucky" since we had arrays and input was given in little endian byte order, but with slices and / or with different byte order it would be a different story. The above presented 2 other ways are more general and work both with slices and arrays.