当值之一为nil时,我尝试对指向指针的映射进行编码时,Gob的Encode返回错误。这似乎与文档相矛盾(但是我可能会误解其含义):
在切片,数组和映射中,即使所有元素均为零,也会传输所有元素,即使是零值元素。
码:
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
在这种情况下,料滴是否有充分的理由失败?似乎两个明显的选择之一都比失败更可取:1)不对任何键值为零的键进行编码,或者2)即使值为零也对所有键进行编码。在当前状态下,最佳实践是递归地扫描我的结构以查看是否有任何nil映射值,如果有则删除这些键吗?如果需要进行此检查,则似乎应该由编码/ gob包而不是用户负责。
此外,规则不是简单地“ gob无法对键值为nil的映射进行编码”,因为如果值类型是slice,则可以接受nil:
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,则将发送指向的值,即type的值int。如果需要,可以在解码器端将此转换反向,例如,如果int在*int要为其设置值的流中找到一个值,则将设置一个指针(类型为*int),指向已解码的int值。
gob
*int
int
因此,如果指针值本身是nil,则gob包没有可以编码的值而不是指针值,则nil指针将指向任何内容。取消引用nil指针是一种运行时恐慌。
nil
在gob上也有记录:基础知识:
指针不被传输,但是指针所指向的事物被传输。即,将值展平。 不允许使用零指针,因为它们没有值。