Gob 无法使用 nil 指针值对地图进行编码
Gob can't encode map with a nil pointer value
Gob 的编码 returns 如果其中一个值为 nil,我尝试将映射编码为指针时出错。这似乎与文档相矛盾(但我可能误解了意思):
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 包而不是用户负责。
此外,规则不是简单的 "gob can't encode maps where a key has a value of nil" 因为如果值类型是切片,则接受 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
,指向的值将被发送,即一个int
类型的值。如果需要,这种转换在解码器端被逆转,例如如果在要为其设置 *int
值的流中找到 int
值,则将设置一个指针(*int
类型)指向已解码的 int
值。
因此,如果指针值本身是 nil
,则没有 gob
包可以编码的值而不是指针值,nil
指针指向任何内容。取消引用 nil
指针是运行时恐慌。
这也记录在 gob: Basics:
Pointers are not transmitted, but the things they point to are transmitted; that is, the values are flattened. Nil pointers are not permitted, as they have no value.
Gob 的编码 returns 如果其中一个值为 nil,我尝试将映射编码为指针时出错。这似乎与文档相矛盾(但我可能误解了意思):
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 包而不是用户负责。
此外,规则不是简单的 "gob can't encode maps where a key has a value of nil" 因为如果值类型是切片,则接受 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
,指向的值将被发送,即一个int
类型的值。如果需要,这种转换在解码器端被逆转,例如如果在要为其设置 *int
值的流中找到 int
值,则将设置一个指针(*int
类型)指向已解码的 int
值。
因此,如果指针值本身是 nil
,则没有 gob
包可以编码的值而不是指针值,nil
指针指向任何内容。取消引用 nil
指针是运行时恐慌。
这也记录在 gob: Basics:
Pointers are not transmitted, but the things they point to are transmitted; that is, the values are flattened. Nil pointers are not permitted, as they have no value.