Как работает custom unmarshal и marshal в go?

В общем, в базе есть таблица из которой тащим данные, есть столбец, у которого некоторые поля заполнены, некоторые равны null. Чтобы все это нормально конвертировалось в структуру, использую sql.NullString. Соответственно получившуюся структуру мне надо отдавать json-oм. Но sql.Nullstring и ему подобные имеют в себе два поля, поэтому json получается "unexpected". В документации нашел, что можно сделать кастомный анмаршал и маршал. Сделал. Только при переопределении метода анмаршал я допустил оплошность и сделал reciever-ом метода не указатель на структуру, а значение. Когда нашел в чем ошибка, сразу встал вопрос, а почему, собственно, анмаршал перестает работать, есть reciever метода - значение. И тот же вопрос про маршал, почему он также перестает работать, если наоборот reciever-oм метода сделать - указатель. Прилагаю код неработающих правильно методов.
type NullString struct {
	sql.NullString
}

func (ns *NullString) MarshalJSON() ([]byte, error) {
	if !ns.Valid {
		return json.Marshal(nil)
	}
	return json.Marshal(ns.String)
}

func (ns NullString) UnmarshalJSON(b []byte) error {
	err := json.Unmarshal(b, &ns.String)
	ns.Valid = err == nil
	return err
}
  • Вопрос задан
  • 1713 просмотров
Решения вопроса 1
@PapaStifflera
Родился, вырос...
The language specifies that if *T implements the methods of an interface I then only a
*T (pointer) value will satisfy I, and not a T (value) value. So encoding/json can't see
that *DecimalE8 implements MarshalJSON because it only has a DecimalE8 value.
It is important to preserve this property, because a value implemented on *T might
assume that it can modify the underlying T value (which, given a value receiver, it
could not).

https://github.com/golang/go/issues/7536
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы