Я столкнулся с каким-то странным поведением с отражением.У меня есть объект типа map[string][]string
, с одним ключом, значение которого является пустым срезом.Когда я использую gob для кодирования этого объекта, а затем декодирую его в другую карту, эти две карты не равны в соответствии с отражением.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 обрабатывает пустые срезы;это странное взаимодействие между сериализацией и гобом.