我在 reflect.DeepEqual 中遇到了一些奇怪的行为。我有一个 type 的对象map[string][]string
,其中一个键的值是一个空切片。当我使用 gob 对该对象进行编码,然后将其解码为另一个映射时,根据 reflect.DeepEqual,这两个映射不相等(即使内容相同)。
package main
import (
"fmt"
"bytes"
"encoding/gob"
"reflect"
)
func main() {
m0 := make(map[string][]string)
m0["apple"] = []string{}
// Encode m0 to bytes
var network bytes.Buffer
enc := gob.NewEncoder(&network)
enc.Encode(m0)
// Decode bytes into a new map m2
dec := gob.NewDecoder(&network)
m2 := make(map[string][]string)
dec.Decode(&m2)
fmt.Printf("%t\n", reflect.DeepEqual(m0, m2)) // false
fmt.Printf("m0: %+v != m2: %+v\n", m0, m2) // they look equal to me!
}
输出:
false
m0: map[apple:[]] != m2: map[apple:[]]
后续实验的几点说明:
如果我创建m0["apple"]
一个非空切片的值,例如m0["apple"] = []string{"pear"}
,则 DeepEqual 返回 true。
如果我将值保留为空切片,但我从头开始而不是使用 gob 构建相同的映射,则 DeepEqual 返回 true:
m1 := make(map[string][]string)
m1["apple"] = []string{}
fmt.Printf("%t\n", reflect.DeepEqual(m0, m1)) // true!
因此,DeepEqual 如何处理空切片并不是严格意义上的问题。这是和 gob 的序列化之间的一些奇怪的交互。