go - 如何漂亮地打印一个字节数组作为字符串的结构?

标签 go

我正在尝试从网络数据中解码动态结构,这里是简化版本。 FmtA[3]byte,需要打印成字符串。所以,这是我通过定义 Bytes3 数据类型的愚蠢实现。 如果使用这种方法,我应该定义Bytes6Bytes4Bytes2

有没有更好的方法将所有字节数组打印为字符串而不是字节数组?

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]}                 
}

最佳答案

您可以创建一个实用程序函数,它可以采用任何结构,使用反射检查字段并相应地设置它们的格式(对不是字节数组的字段使用默认值,但强制字节数组打印为字符串)。

例如:

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 playground 中定义的结构运行的示例:

https://play.golang.org/p/zGZM5S8UMWZ

关于go - 如何漂亮地打印一个字节数组作为字符串的结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57429942/

相关文章:

go - 使用 channel 在go中实现重试机制

Golang 使用 golang dep with dep

在 %PATH% 中找不到 GCC

go - Go 如何在没有内置 Comparable 接口(interface)的情况下处理比较?

windows - 戈朗 : how can I call win32 API without cgo?

go - 在使用 gin gonic 进行负载测试期间打开的文件过多

go - 如何触发电报机器人发送消息

go - 为什么 Scanf() 不能为我正常工作?

Golang “net/http” DetectContentType 错误

go - 如何获得索引总数