Я пытаюсь использовать рефлексию, чтобы взять поля времени из структуры и через пользовательский функционал UnmarshallJSON, посмотреть, какие из них встречаются как значение time.IsZero, а какие нет. Они встречаются как * time.Time, и я не хочу использовать omitempty (как я не могу, и нужно, чтобы поле было очищено и сохранено как таковое). Сейчас я проверяю каждое поле отдельно, но мне было интересно, есть ли способ сделать это с помощью отражения, чтобы сделать его более устойчивым, если было добавлено другое поле времени, мне не нужно было добавлять соответствующую проверку для него.
Прямо сейчас вот как я это делаю:
type A struct {
X *time.Time `json:"x"`
Y *time.Time `json:"y"`
}
func (a *A) UnmarshalJSON(b []byte) (err error) {
type Alias A
s := &struct {
X time.Time `json:"x"`
Y time.Time `json:"y"`
}{
Alias: (*Alias)(a),
}
if err := json.Unmarshal(b, &s); err != nil {
return err
}
if s.X.IsZero() {
a.X = nil
} else {
a.X = &s.X
}
if s.Y.IsZero() {
a.Y = nil
} else {
a.Y = &s.Y
}
Я бы предпочел не проверять каждое поле времени и вместо этого делать что-то подобное
values := reflect.ValueOf(&s).Elem()
for i := 0; i < values.NumField(); i++ {
fieldName := values.Type().Field(i).Name
fieldValue := values.Field(i).Interface()
if fieldValue == nil {
a.fieldName = nil
} else {
a.fieldName = &s.fieldName
}
Проблема возникает, когда я пытаюсь сделать a.fieldName или s.fieldName, я что-то упустил? кто-нибудь сталкивался с этим или (надеюсь) решил эту проблему?