[Solved] Go language gob serialization pointer cannot be addressed Error

1. Error description

An error occurs when using gob serialization: gob: addressable value of type * big. Float

Scenario:

Serializing a data structure contains a map field, where value is the big. Float structure type

type SideBlock {
  ...
  Varphi map[string]big.Float
  ...
}


func (b *SideBlock) Serialization() []byte {
	var res bytes.Buffer
	encoder := gob.NewEncoder(&res)
	err := encoder.Encode(b)
	if err != nil {
		logger.Error("Serialization err : ", err)
	}
	return res.Bytes()
}

Go version: go version go1.16.5 Darwin/arm64

OS: Mac OS BigSur 11.5.2

2. Error reason

The answer is found in issue:

He has a problem using URL. URL as the key of map

The problem lies in the pointer receiver of marshalbinary . If we want to use this structure as a key or value, we need to implement the marshalbinary method for special fields

personal understanding: when a map field of a structure has another structure instead of a pointer to the structure, it is a copy of the structure rather than itself during serialization, so it is difficult to address </ font>

3. Solution

Method 1:

https://play.golang.org/p/dK7SsqahtAd

package main

import (
	"encoding/gob"
	"fmt"
	"io/ioutil"
)

type T struct {
}

func (t *T) String() string { return "" }

func (t T) MarshalBinary() (text []byte, err error) {
	return []byte(t.String()), nil
}

func main() {
	m := make(map[T]int)
	m[T{}] = 0
	e := gob.NewEncoder(ioutil.Discard)
	fmt.Println(e.Encode(m))
}

Method 2:

Change big. Float into a pointer, that is, the field becomes varphi map [string] * big. Float

Read More: