为了账号安全,请及时绑定邮箱和手机立即绑定

gob 尝试解码 nil 值导致 EOF 错误

gob 尝试解码 nil 值导致 EOF 错误

Go
慕的地6264312 2022-01-17 20:05:49
我需要使用gob对一些数据进行编码,但是,我发现无法正确处理“type nil”(转到 1.6.2)https://play.golang.org/p/faypK8uobFpackage mainimport (    "bytes"    "encoding/gob"    "log")type T struct {    A int}func init() {    gob.Register(map[string]interface{}{})    gob.Register(new(T))}func main() {    bys := bytes.NewBuffer(nil)    gob.NewEncoder(bys).Encode(map[string]interface{}{        "v": (*T)(nil),    })    out := map[string]interface{}{}    if err := gob.NewDecoder(bys).Decode(&out); err != nil {        log.Panic(err)    }    return}输出:panic: EOF
查看完整描述

1 回答

?
尚方宝剑之说

TA贡献1788条经验 获得超4个赞

你正在吞下一个error返回的Encoder.Encode():


err := gob.NewEncoder(bys).Encode(map[string]interface{}{

    "v": (*T)(nil),

})

if err != nil {

    fmt.Println(err)

}

输出:


gob: gob: cannot encode nil pointer of type *main.T inside interface

这是由未导出的方法生成的Encoder.encodeInterface()。引用encode.go未导出的方法Encoder.encodeInterface():


// Gobs can encode nil interface values but not typed interface

// values holding nil pointers, since nil pointers point to no value.

elem := iv.Elem()

if elem.Kind() == reflect.Ptr && elem.IsNil() {

    errorf("gob: cannot encode nil pointer of type %s inside interface", iv.Elem().Type())

}

因此,您Encoder.Encode()失败了,它不会向其输出(即bys缓冲区)写入任何内容,因此尝试从中读取(解码)任何内容都会导致 EOF。


但是为什么你不能编码一个interface{}持有nil指针的值呢?引用包文档encoding/gob:


指针不被传输,但它们指向的东西被传输;也就是说,这些值是扁平的。


您interface{}包含一个指针类型的值,但该指针是nil,它不指向任何内容,它不能被展平。


这是 github 上的一个相关问题:encoding/gob: panic on encoding nil pointer #3704


拉斯:


gob 不知道指针是什么:一切都变平了。将 nil 指针放在 interface{} 值中会创建一个非零值(它不是 nil 接口),gob 无法发送(它不能表示“nil 指针”)。


罗布·派克:


正确的。只有具体值本身是可传输的,才能传输接口值。至少现在,这相当于说不能发送持有类型化 nil 指针的接口。


查看完整回答
反对 回复 2022-01-17
  • 1 回答
  • 0 关注
  • 233 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号