dsomm80482
2014-07-22 21:37
浏览 67
已采纳

GoLang:读取字节并将其转换为结构字段

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)
        reader.Read(value)

        var num uint8
        err := binary.Read(bytes.NewBuffer(value[:]), binary.LittleEndian, &num)
        if err != nil { return err }
        field.SetUint(int64(num))
    // 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.

    评论
    解决 无用
    打赏 举报