使用 reader 从 []byte 读入结构时出错

Error while reading into a struct from a []byte using a reader

我正在尝试从 []byte 变量中读取结构。

当我尝试读取单个变量时,我可以让它工作,但是当我尝试直接读入结构时,我收到以下错误:

 panic: reflect: reflect.Value.SetInt using value obtained using unexported field

这是我试过的:

package main

import (
    "bytes"
    "encoding/binary"
    "fmt"
)

type foo struct {
    a int8
    b int8
}

func main() {
    var data1 int8
    var data2 foo
    
    b := []byte{0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40}
    
    buf := bytes.NewReader(b)

    // READ data1 (int8)
    fmt.Println("READ data1")
    err := binary.Read(buf, binary.LittleEndian, &data1)
    if err != nil {
        fmt.Println("binary.Read failed:", err)
    }
    fmt.Println(data1)

    // READ data2 (struct with two int8s)
    fmt.Println(data2)
    err = binary.Read(buf, binary.LittleEndian, &data2)
    if err != nil {
        fmt.Println("binary.Read failed:", err)
    }   
    fmt.Print(data2)
}

这是完整的错误:

READ data1
24
{0 0}
panic: reflect: reflect.Value.SetInt using value obtained using unexported field

goroutine 1 [running]:
reflect.flag.mustBeAssignableSlow(0x1a3)
    /usr/local/go-faketime/src/reflect/value.go:257 +0x1b9
reflect.flag.mustBeAssignable(...)
    /usr/local/go-faketime/src/reflect/value.go:247
reflect.Value.SetInt(0x4a9760, 0xc00010000c, 0x1a3, 0x2d)
    /usr/local/go-faketime/src/reflect/value.go:1633 +0x3b
encoding/binary.(*decoder).value(0xc00006ae50, 0x4a9760, 0xc00010000c, 0x1a3)
    /usr/local/go-faketime/src/encoding/binary/binary.go:574 +0x9a5
encoding/binary.(*decoder).value(0xc00006ae50, 0x4b17e0, 0xc00010000c, 0x199)
    /usr/local/go-faketime/src/encoding/binary/binary.go:558 +0x3a8
encoding/binary.Read(0x4e2460, 0xc00010c000, 0x4e2ea0, 0x58c588, 0x4a5d80, 0xc00010000c, 0x0, 0x0)
    /usr/local/go-faketime/src/encoding/binary/binary.go:259 +0x33a
main.main()
    /tmp/sandbox052619529/prog.go:36 +0x358

Program exited: status 2.

可在此处找到可重现的示例:

https://play.golang.org/p/4UWy2OuDAsL

问题是您的 foo 结构字段未导出(第一个字母未大写),因此反射包无法访问那些用于写入的字段(它仍然可以读取未导出的字段)。

将您的结构更改为:

type foo struct {
    A int8
    B int8
}