Итак, сначала: Да, использование этой переменной c (глобальной) будет проблемой для одновременного использования / доступа. Это не способ go.
Если ваш лог c проверки является контекстным (как вы сказали: если флаг ложный, то определенные ограничения применяются к другому полю), тогда реализация простого Validate
функция довольно проста. Я знаю, что используемый вами пакет поддерживает этот тип вещей, но внешний пакет почти всегда будет иметь довольно общий характер c. По крайней мере, вы в конечном итоге выполните утверждения типа. Последнее, что я проверил, вам все еще нужен явный вызов для проверки validator.Validate()
, так почему бы не переместить его в метод вашего типа?
type newAppRegister struct {} // your type
func (n newAppRegister) Validate() error {
if err := validator.Validate(n); err != nil {
return err
}
// at this point, we now the flag field isn't nit, because it passed validation
if !*n.SomeFlag {
// validate ComputeLevel here
}
return nil
}
Нет необходимости в утверждениях типа, не говоря уже о отражении. Я бы даже сказал, что с этими двумя полями нет необходимости в пакете валидатора. Вы можете сделать то же самое с помощью стандартных тегов JSON:
type Foo struct {
SomeFlag *bool `json:"some_flag,omitempty"`
ComputeLevel string `json:"compute_level"`
}
func (f Foo) Validate() error {
if f.SomeFlag == nil {
return ErrSomeFlagRequired
}
if !*f.SomeFlag {
// validate ComputeLevel
}
return nil
}
Это довольно просто использовать:
f := Foo{}
if err := json.Unmarshal([]byte(payload), &f); err != nil {
// some shady JSON was submitted
}
if err := f.Validate(); err != nil {
// JSON was technically valid, but payload made no sense
}
// handle valid request