llx*_*llx 1 null pointers go gob
我需要使用它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
}
Run Code Online (Sandbox Code Playgroud)
输出:
panic: EOF
Run Code Online (Sandbox Code Playgroud)
你吞咽了一个error退回Encoder.Encode():
err := gob.NewEncoder(bys).Encode(map[string]interface{}{
"v": (*T)(nil),
})
if err != nil {
fmt.Println(err)
}
Run Code Online (Sandbox Code Playgroud)
输出:
gob: gob: cannot encode nil pointer of type *main.T inside interface
Run Code Online (Sandbox Code Playgroud)
这是由未导出的方法生成的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())
}
Run Code Online (Sandbox Code Playgroud)
所以你Encoder.Encode()失败了,它没有写任何东西给它的输出(这是bys缓冲区),所以试图从它读取(解码)任何东西导致EOF.
但为什么你不能编码一个interface{}持有nil指针的值?引用包文档encoding/gob:
指针不被传输,但它们指向的东西被传输; 也就是说,这些值是扁平化的.
你interface{}包含一个指针类型的值,但是指针是nil,它指向什么,它不能被展平.
这是关于github的相关问题:encoding/gob:panic on encoding nil pointer#3704
拉斯:
gob不知道指针是什么:一切都变平了.将nil指针放在interface {}值中会创建一个gob无法发送的非零值(它不是nil接口)(它不能表示'nil指针').
Rob Pike:
正确.仅当具体值本身是可传输的时,才能传输接口值.至少现在,这相当于说不能发送包含类型的nil指针的接口.
| 归档时间: |
|
| 查看次数: |
1356 次 |
| 最近记录: |