Go copy bytes into struct fields with reflection

Issue

How can I iterate over a byte slice and assign them to the fields of a struct?

type s struct {
  f1 []byte
  f2 []byte
  f3 []byte
}

func S s {
  x := s{}
  x.f1 = make([]byte, 4)
  x.f1 = make([]byte, 2)
  x.f1 = make([]byte, 2)
  return x
}

func main() {
  data := []byte{83, 117, 110, 83, 0, 1, 0, 65}

  Z := S()
  //pesudo code from here
  i:= 0
  for field in Z {
    field = data[i:len(field)]
    i += len(field)
  }

Expecting:

  • f1 = [83,117,110,83]
  • f2 = [0,1]
  • f3 = [0,65]

I’ve done this in C/C++ before but I can’t figure out how to do it in Go. I need the assigning function to be generic as I’m going to have several different structs some of which may not exist in the stream.

Ideally I want to pass in the initialized struct and my code would iterate over the struct fields filling them in.

Solution

Leverage the reflection code in the binary/encoding package.

Step 1: Declare the fields as arrays instead of slices.

type S struct {
  F1 [4]byte
  F2 [2]byte
  F3 [2]byte
}

Step 2: Decode the data to the struct using binary.Read

var s S
data := []byte{83, 117, 110, 83, 0, 1, 0, 65}
err := binary.Read(bytes.NewReader(data), binary.LittleEndian, &s)
if err != nil {
    log.Fatal(err)
}

Step 3: Done!

fmt.Print(s) // prints {[83 117 110 83] [0 1] [0 65]}

https://go.dev/play/p/H-e8Lusw0RC

Answered By – Fluent Gopher

Answer Checked By – Marie Seifert (GoLangFix Admin)

Leave a Reply

Your email address will not be published.