Gob无法使用nil指针值编码地图 [英] Gob can't encode map with a nil pointer value

查看:321
本文介绍了Gob无法使用nil指针值编码地图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当值之一为nil时,我尝试对指向指针的映射进行编码时,Gob的Encode返回错误.这似乎与文档相矛盾(但是我可能会误解其含义):

Gob's Encode returns an error when I try to encode a map to pointers if one of the values is nil. This seems to contradict the docs (but I may be misinterpreting the meaning):

在切片和数组以及映射中,即使所有元素均为零,也将传输所有元素,即使是零值元素.

In slices and arrays, as well as maps, all elements, even zero-valued elements, are transmitted, even if all the elements are zero.

代码:

package main

import (
    "bytes"
    "encoding/gob"
)

type Dog struct {
    Name string
}

func main() {
    m0 := make(map[string]*Dog)
    m0["apple"] = nil

    // Encode m0 to bytes
    var network bytes.Buffer
    enc := gob.NewEncoder(&network)
    err := enc.Encode(m0)
    if err != nil {
        panic(err) // Output: panic: gob: encodeReflectValue: nil element
    }
}

输出:

panic: gob: encodeReflectValue: nil element

在这种情况下,gob是否有充分的理由失败?似乎两个明显的选择之一都比失败更可取:1)不对具有零值的键进行编码,或者2)即使值为零也对所有键进行编码.在目前的情况下,最佳实践是递归地扫描我的结构以查看是否有nil映射值,如果有的话将其删除吗?如果需要进行此检查,则似乎应该由encoding/gob包而不是用户负责.

Is there a good reason for gob to fail in this case? It seems that either of the two obvious options are preferable to failure: 1) don't encode any keys with values that are zero-valued or 2) encode all keys even if the values are zero-valued. With the current state of things, is the best practice to recursively scan through my struct to see if there are any nil map values, and delete those keys if so? If this check is required, it seems like it should be the responsibility of the encoding/gob package, not the user.

此外,规则不只是密钥不能对键值为nil的映射进行编码",因为如果值类型是切片,则可以接受nil:

Further, the rule isn't simply "gob can't encode maps where a key has a value of nil" because if the value type is a slice, then nil is accepted:

func main() {
    m0 := make(map[string][]string)
    m0["apple"] = nil

    // Encode m0 to bytes
    var network bytes.Buffer
    enc := gob.NewEncoder(&network)
    err := enc.Encode(m0) // err is nil
    if err != nil {
        panic(err) // doesn't panic
    }
}

推荐答案

gob编码的流没有指针的概念.如果对诸如*int之类的指针值进行编码,则将发送指向的值,即类型为int的值.如果需要,例如在解码器侧将该变换逆转.如果在要为其设置*int值的流中找到int值,则将设置一个指针(类型为*int),该指针指向已解码的int值.

The gob encoded stream has no notion of pointers. If you encode a pointer value such as *int, the pointed value will be sent, that is, a value of type int. This transformation is reversed at the decoder side if needed, e.g. if an int value is found in the stream for which an *int value is to be set, a pointer (of type *int) will be set pointing to the decoded int value.

因此,如果指针值本身是nil,则没有任何gob包可以编码的值,而不是指针值,nil指针则不指向任何内容.取消引用nil指针是一种运行时恐慌.

So if a pointer value itself is nil, there is no value that the gob package could encode instead of the pointer value, a nil pointer points to nothing. Dereferencing a nil pointer is a runtime panic.

gob:基础知识:

指针不被传输,但是指针所指向的东西被传输;即,将值展平. 不允许使用无指针,因为它们没有价值.

这篇关于Gob无法使用nil指针值编码地图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆