代码之家  ›  专栏  ›  技术社区  ›  M.E.

使用读取器从[]字节读入Go中的结构时出错

  •  -1
  • M.E.  · 技术社区  · 5 年前

    我正在尝试从[]字节变量读取结构。

    当我尝试读取单个变量时,我可以使其工作,但当尝试直接读取到结构时,我会遇到以下错误:

     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

    0 回复  |  直到 5 年前
        1
  •  1
  •   meshkati    5 年前

    问题是你的 foo 结构字段是未报告的(第一个字母不是大写的),因此reflect包无法访问这些字段进行写入(它仍然可以读取未报告的字段)。

    type foo struct {
        A int8
        B int8
    }