简体   繁体   English

料滴尝试解码nil值会导致EOF错误

[英]gob attempting to decode nil value results in EOF error

I need to use the gob to encode some data, however, I find that "type nil" can not be processed correctly (go 1.6.2) 我需要使用gob编码一些数据,但是,我发现无法正确处理“类型nil”(转到1.6.2)

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

package main

import (
    "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
}

Output: 输出:

panic: EOF

You are swallowing an error returned by Encoder.Encode() : 您正在吞下Encoder.Encode()返回的error

err := gob.NewEncoder(bys).Encode(map[string]interface{}{
    "v": (*T)(nil),
})
if err != nil {
    fmt.Println(err)
}

Output: 输出:

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

This is generated by unexported method Encoder.encodeInterface() . 这是由未导出的方法Encoder.encodeInterface()生成的。 Quoting from encode.go , unexported method 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())
}

So your Encoder.Encode() fails, it writes nothing to its output (which is the bys buffer), so attempting to read (decode) anything from it results in EOF. 因此,您的Encoder.Encode()失败,它不向其输出(即bys缓冲区)写入任何内容,因此尝试从中读取(解码)任何内容都会导致EOF。

But why can't you encode an interface{} value holding a nil pointer? 但是,为什么不能编码包含nil指针的interface{}值呢? Quoting from the package doc of encoding/gob : 引用来自encoding/gob的软件包文档:

Pointers are not transmitted, but the things they point to are transmitted; 指针不被传输,但是指针所指向的事物被传输。 that is, the values are flattened. 即,将值展平。

Your interface{} contains a value of pointer type, but that pointer is nil , it points to nothing, it cannot be flattened. 您的interface{}包含一个指针类型的值,但该指针为nil ,它指向无内容,不能被展平。


Here is a related issue on github: encoding/gob: panic on encoding nil pointer #3704 这是github上的一个相关问题: encoding / gob:编码nil指针时出现恐慌#3704

Russ: 拉斯:

gob doesn't know what a pointer is: everything gets flattened. gob不知道指针是什么:一切都变平了。 Putting a nil pointer in an interface{} value creates a non-zero value (it's not the nil interface) that gob cannot send (it can't express 'nil pointer'). 将nil指针放在interface {}值中会创建一个gob无法发送(它不能表示“ nil指针”)的非零值(这不是nil接口)。

Rob Pike: 罗伯·派克:

Correct. 正确。 An interface value can be transmitted only if the concrete value itself is transmittable. 仅当具体值本身可传输时,才能传输接口值。 At least for now, that's equivalent to saying that interfaces holding typed nil pointers cannot be sent. 至少就目前而言,这相当于说无法发送包含类型为nil指针的接口。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM