【问题标题】:gob attempting to decode nil value results in EOF errorgob 尝试解码 nil 值导致 EOF 错误
【发布时间】:2016-10-24 00:58:35
【问题描述】:

我需要使用gob对一些数据进行编码,但是我发现“type nil”无法正确处理(转到1.6.2)

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
}

输出:

panic: EOF

【问题讨论】:

    标签: pointers go null gob


    【解决方案1】:

    你正在吞食Encoder.Encode()返回的error:

    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。

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

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

    你的interface{} 包含一个指针类型的值,但是那个指针是nil,它什么都不指向,它不能被展平。


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

    拉斯:

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

    罗伯·派克:

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

    【讨论】:

      猜你喜欢
      • 2016-01-09
      • 2018-01-12
      • 1970-01-01
      • 1970-01-01
      • 2019-08-07
      • 2022-11-23
      • 2021-05-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多