我正在尝试从网络数据中解码动态结构,这是简化版本。 FmtA
是[3]byte
,需要打印为字符串。因此,这是我通过定义Bytes3
数据类型的愚蠢实现。
如果使用此方法,则应定义Bytes6
,Bytes4
,Bytes2
。
有没有更好的方法将所有字节数组打印为字符串而不是字节数组?
package main
import "fmt"
type Bytes3 [3]byte
type FmtA struct {
Field1 Bytes3
Field2 [6]byte
Field3 uint8
}
type FmtB struct {
Field1 uint16
Field2 [4]byte
Field3 [2]byte
}
func (b Bytes3) String() string {
v := [3]byte(b)
return string(v[:])
}
func main() {
a := FmtA{[3]byte{'a', 'b', 'c'}, [6]byte{'d', 'e', 'f', 'g', 'h', 'i'},
36}
b := FmtB{42, [4]byte{'a', 'b', 'c', 'd'}, [2]byte{'e', 'f'}}
var i interface{} // simulate the received variable type
i = a
fmt.Printf("a=%+v\n", i)
i = b
fmt.Printf("b=%+v\n", i)
// Output:
// a={Field1:abc Field2:[100 101 102 103 104 105] Field3:36}
// b={Field1:42 Field2:[97 98 99 100] Field3:[101 102]}
}
答案 0 :(得分:1)
您可以创建一个实用程序函数,该函数可以采用任何结构,使用反射检查字段并进行相应的格式化(对于不是字节数组,但强制字节数组打印为字符串的字段,请使用默认值)。
例如:
func Struct2String(theStruct interface{}) string {
reflectV := reflect.ValueOf(theStruct)
structType := reflectV.Type()
b := &bytes.Buffer{}
b.WriteString("{")
for i := 0; i < reflectV.NumField(); i++ {
if i > 0 {
b.WriteString(" ")
}
b.WriteString(structType.Field(i).Name)
b.WriteString(": ")
fieldValue := reflectV.Field(i)
fieldType := reflectV.Field(i).Type()
fieldKind := reflectV.Field(i).Kind()
if (fieldKind == reflect.Slice || fieldKind == reflect.Array) && fieldType.Elem().Kind() == reflect.Uint8 {
fmt.Fprintf(b, "%s", fieldValue)
} else {
fmt.Fprint(b, fieldValue)
}
}
b.WriteString("}")
return b.String()
}
在这里您可以看到示例使用在Go游乐场中定义的结构运行: