2014-07-22 21:37
浏览 67


I am reading from an io.Reader into a Struct, field by field.

// structFields returns a sequence of reflect.Value
for field := range structFields {
    switch field.Kind() {
    case reflect.String:
        // Omitted
    case reflect.Uint8:
        value := make([]byte, 2)

        var num uint8
        err := binary.Read(bytes.NewBuffer(value[:]), binary.LittleEndian, &num)
        if err != nil { return err }
    // Case statements for each of the other uint and int types omitted

Unfortunately the block for reflect.Uint8 needs to be repeated for each of the Uint and Int data types since I need to create the var num correctly in each case.

Is there a way I can simplify this switch statement?

  • 写回答
  • 好问题 提建议
  • 追加酬金
  • 关注问题
  • 邀请回答

1条回答 默认 最新

  • duaj39673 2014-07-23 00:12

    Instead of using var num uint8 and field.SetUint(int64(num)) just pass a pointer to the struct field to binary.Read:

    ptr := field.Addr().Interface()
    err := binary.Read(bytes.NewBuffer(value[:]), binary.LittleEndian, ptr)

    And make the case statement say:

    case reflect.Uint8, reflect.Int, reflect.Uint, ...:

    Then you need to deal with differently-sized numbers. Fortunately you can just pass your reader directly to binary.Read and it'll take care of it:

    err := binary.Read(reader, binary.LittleEndian, ptr)

    Finally, as FUZxxl says, you can just pass a pointer to the entire struct to binary.Read and it'll do all this for you.

    解决 无用
    打赏 举报