Gob не может закодировать карту с нулевым значением указателя
Код Gob возвращает код ошибки, когда я пытаюсь закодировать карту в указатели, если одно из значений равно nil. Это, кажется, противоречит документации (но я могу неправильно истолковывать значение):
В срезах и массивах, а также на картах передаются все элементы, даже элементы с нулевым значением, даже если все элементы равны нулю.
Код:
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) кодировать все ключи, даже если значения имеют нулевое значение. С текущим состоянием вещей, является ли лучшая практика для рекурсивного сканирования моей структуры, чтобы увидеть, есть ли какие-либо значения карты ноль, и удалить эти ключи, если так? Если эта проверка требуется, кажется, что ответственность за это должен выполнять пакет encoding/gob, а не пользователь.
Кроме того, правило не просто "gob не может кодировать карты, где ключ имеет значение 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
}
}
1 ответ
gob
закодированный поток не имеет понятия указателей. Если вы кодируете значение указателя, такое как *int
указанное значение будет отправлено, то есть значение типа int
, Это преобразование инвертируется на стороне декодера, если необходимо, например, если int
значение находится в потоке, для которого *int
значение должно быть установлено, указатель (типа *int
) будет установлен указатель на декодированный int
значение.
Так что, если само значение указателя nil
нет значения, что gob
пакет может кодировать вместо значения указателя, nil
указатель указывает на ничто. Разыменование nil
указатель это паника во время выполнения.
Это также задокументировано в gob: Основы:
Указатели не передаются, но передаются то, на что они указывают; то есть значения сглаживаются. Нулевые указатели не допускаются, так как они не имеют значения.