package main
import (
"fmt"
"strings"
)
// Есть такой интерфейс:
type validator interface {
Validate() error
}
// есть такой тип, удовлетворяющий интерфейсу:
type FieldEmail string
func (fi FieldEmail) Validate() error {
if !strings.Contains(string(fi), "@") {
return fmt.Errorf("invalid field")
}
return nil
}
// Есть общая функция, которая проверяет поля:
func checkValidators(validators ...validator) error {
for _, v := range validators {
if v == nil { // здесь ошибка
continue
}
if err := v.Validate(); err != nil {
return err
}
}
return nil
}
func main() {
// здесь проблемы нет
fmt.Printf("Error: %v\n", checkValidators(FieldEmail("test@test")))
// но если у меня *FieldEmail, то в checkValidators условие `v == nil` не срабатывает
var email *FieldEmail
fmt.Printf("Error: %v\n", checkValidators(email))
}
T.к. *FieldEmail на самом деле является полем структуры и таких полей много, не хочется каждое поле проверять на != nil до передачи в функцию checkValidators().
Решение, которое я нашел, использует рефлексию, чего тоже бы хотелось избежать.
Код на playground
Есть какие-то идеи, как еще это можно реализовать?