Дженерики Голанга

Попытка создать абстрактную службу аутентификации с использованием универсального типа. Я хотел создать пакет Auth, который будет иметь метод New() для инициализации, но в настоящее время столкнулся с проблемой, которую я могу решить. У кого-нибудь есть идеи, возможно ли это вообще, и если это вообще способ решения проблемы?

type Register[T any] interface {
    SignUp(T) (*AuthEntity, error)
}

type AuthEntity struct {
    ID        string
    UpdatedAt time.Time
    CreatedAt time.Time
}

type AuthService[T any] struct {
    Register[T]
}

type PasswordStrategy struct{}
type SignUpViaPassword struct {
    Email    string
    Password string
}

func (s PasswordStrategy) SignUp(signUpData SignUpViaPassword) (*AuthEntity, error) {
    return &AuthEntity{ID: "email@gmail.com"}, nil
}

func New[T any](register Register[T]) AuthService[T] {
    return AuthService[T]{
        Register: register,
    }
}

type GoogleStrategy struct{}
type SignUpViaGoogle struct {
    Token string
}

func (s GoogleStrategy) SignUp(signUpData SignUpViaGoogle) (*AuthEntity, error) {
    return &AuthEntity{}, nil
}

func main() {
    // This works as expected
    authService := AuthService[SignUpViaPassword]{
        Register: PasswordStrategy{},
    }
    entity, err := authService.SignUp(SignUpViaPassword{Password: "Kako ide", Email: "email@gmail.com"})
    if err != nil {
        log.Println(err)
    }
    log.Println(entity)
    // This also works as expected
    googleAuthService := AuthService[SignUpViaGoogle]{
        Register: GoogleStrategy{},
    }
    entity2, err := authService.SignUp(SignUpViaPassword{Password: "Kako ide", Email: "email@gmail.com"})
    if err != nil {
        log.Println(err)
    }
    log.Println(entity2)

    // this doesn't work and returns error  type PasswordStrategy of PasswordStrategy{} does not match Register[T] (cannot infer T)
    New(PasswordStrategy{})
    New(GoogleStrategy{})
}

Запуск PHP на IIS без использования программы установки веб-платформы
Запуск PHP на IIS без использования программы установки веб-платформы
Установщик веб-платформы, предлагаемый компанией Microsoft, перестанет работать 31 декабря 2022 года. Его закрытие привело к тому, что мы не можем...
Оптимизация React Context шаг за шагом в 4 примерах
Оптимизация React Context шаг за шагом в 4 примерах
При использовании компонентов React в сочетании с Context вы можете оптимизировать рендеринг, обернув ваш компонент React в React.memo сразу после...
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
Настройка шаблона Metronic с помощью Webpack и Gulp
Настройка шаблона Metronic с помощью Webpack и Gulp
Я пишу эту статью, чтобы поделиться тем, как настроить макет Metronic с помощью Sass, поскольку Metronic предоставляет так много документации, и они...
Уроки CSS 6
Уроки CSS 6
Здравствуйте дорогие читатели, я Ферди Сефа Дюзгюн, сегодня мы продолжим с вами уроки css. Сегодня мы снова продолжим с так называемых классов.
Что такое Css? Для чего он используется?
Что такое Css? Для чего он используется?
CSS, или "Каскадные таблицы стилей", - это язык стилей, используемый в веб-страницах. CSS является одним из основных инструментов веб-разработки...
2
0
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Он не может сделать вывод, каким должен быть T, поэтому вы можете указать его явно:

New[SignUpViaPassword](PasswordStrategy{})

Я знаю об этом, но в этом случае я не могу передать другую реализацию интерфейсов, таких как GoogleSignUpStrategy.

Petar Arandjic 11.02.2023 22:47

Почему нет? Однако это вернет другой тип службы.

Burak Serdar 11.02.2023 22:55

Я отредактировал рассматриваемый код, возможно, это даст вам лучшее представление о том, чего я хочу достичь.

Petar Arandjic 12.02.2023 07:29

@PetarArandjic New[SignUpViaPassword](PasswordStrategy{}) и New[SignUpViaGoogle](GoogleStrategy{}) у вас не работают?

mkopriva 12.02.2023 08:08

Другие вопросы по теме