2

结构如下:

type Auth_msg struct {
    Msg_class       [2]byte
    Msg_content_pty [2]byte

我对在 Go 中使用 Reflect 很新鲜,我遇到了这个:

panic: reflect: call of reflect.Value.Bytes on array Value

当我运行时会发生这种情况val.Field(i).Bytes(),但是当我尝试打印它时:fmt.PrintLn(val.Field(i))它会打印出正确的数组。

我只是想知道,如何在数组或切片中检索 Msg_class?

4

1 回答 1

0

array在 Go 中,an和 a是有区别的sliceValue.Bytes()显式仅适用于字节片(链接到文档)。
注意:我不知道为什么它不处理字节数组;它可能是这样写的,它使实现reflect.Bytes()更简单。无论如何:切片绝对是 Go 中的常见用例,并且很容易将数组转换为切片:


您可以创建一个slice指向arrayusing [:]

    v := reflect.ValueOf(msg.Msg_class)
    fmt.Println("kind :", v.Kind()) // prints 'array'
    // fmt.Printf("bytes : % x\n", v.Bytes())  // panics

    v = reflect.ValueOf(msg.Msg_class[:])
    fmt.Println("kind :", v.Kind())        // prints 'slice'
    fmt.Printf("bytes : % x\n", v.Bytes()) // works

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


要使用反射将数组转换为切片,您可以调用.Slice().reflect.Value

文档中提到的一个约束是数组值必须是可寻址的。
我还没有整理出所有细节,但是确保反射值可寻址的一种方法是调用reflect.ValueOf()指针然后调用.Elem()该指针值:

var arr [2]byte
arr[0] = 'g'
arr[1] = 'o'

// take ValueOf a *pointer* to your array, and let reflect dereference it :
v := reflect.ValueOf(&arr).Elem()
// this sets the "canAddr" flag on this value
fmt.Println("arr value - CanAddr() :", v.CanAddr()) // prints 'true'
slice := v.Slice(0, v.Len())
fmt.Printf("arr bytes : % x\n", slice.Bytes()) // prints '67 6f'

// for a field inside a struct : take a pointer to the struct
var msg Auth_msg
msg.Msg_class[0] = 'a'
msg.Msg_class[1] = 'z'

v = reflect.ValueOf(&msg).Elem()
fmt.Println("msg value - CanAddr() :", v.CanAddr()) // prints 'true'

// now reflect accepts to call ".Slice()" on one of its fields :
field := v.FieldByName("Msg_class")
slice = field.Slice(0, field.Len())
fmt.Printf("msg.Msg_class bytes : % x\n", slice.Bytes()) // prints '61 7a'

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

于 2021-01-29T08:05:35.393 回答