接口无法使用方法,即使它们是相同类型的。

huangapple go评论180阅读模式
英文:

Interface is unable to use method even though they are of the same type

问题

我有一个阶段性问题。在我看来,它看起来完全正确,但我的IDE一直显示这个错误,无法编译。

  1. Cannot use 'userRepo' (type *UserRepo) as the type UserRepository Type does not
  2. implement 'UserRepository' need the method: GetByEmail(email string) (*User, error)
  3. have the method: GetByEmail(email string) (*User, error)

UserRepository.go

  1. type UserRepo struct {
  2. db *mongo.Client
  3. collection *mongo.Collection
  4. }
  5. func (m *UserRepo) GetByEmail(email string) (*User, error) {
  6. ctx := context.Background()
  7. var user *User
  8. err := m.collection.FindOne(ctx, bson.M{"username": email}).Decode(&user)
  9. if err != nil {
  10. return &User{}, err
  11. }
  12. return user, nil
  13. }
  14. func NewUserRepository(client *mongo.Client, collection *mongo.Collection) *UserRepo {
  15. return &UserRepo{
  16. db: client,
  17. collection: collection,
  18. }
  19. }

LoginService.go

  1. type Login struct {
  2. helper pkg.Helper
  3. user User
  4. res LoginResponse
  5. repo Repository
  6. userRepo UserRepository
  7. tokenRepo TokenRepository
  8. cfg config.Config
  9. validator *validator.Validator
  10. }
  11. type UserRepository interface {
  12. GetByEmail(email string) (*User, error)
  13. }
  14. func (l *Login) CreateAccountHandler(w http.ResponseWriter, r *http.Request) {
  15. ......
  16. _, err = l.userRepo.GetByEmail(email)
  17. // Check if the username is already taken.
  18. if err != nil {
  19. http.Error(w, "Username already taken", http.StatusConflict)
  20. json.NewEncoder(w).Encode(failedResponse)
  21. return
  22. }
  23. }
  24. func NewLoginService(repository Repository, tokenRepo TokenRepository, userRepo UserRepository) *Login {
  25. return &Login{
  26. helper: pkg.Helper{},
  27. repo: repository,
  28. userRepo: userRepo,
  29. tokenRepo: tokenRepo,
  30. validator: validator.New(),
  31. }
  32. }

方法名和类型都是相同的。

main.go

  1. // Login
  2. loginCollection := client.Database(cfg.MongoConfig.DBName).Collection(cfg.MongoConfig.LoginCollection)
  3. loginRepo := login.NewLoginRepository(client, loginCollection)
  4. usersCollection := client.Database(cfg.MongoConfig.DBName).Collection(cfg.UsersConfig.UserCollection)
  5. userRepo := data.NewUserRepository(client, usersCollection)
  6. loginService := login.NewLoginService(loginRepo, tokenRepo, userRepo) // 错误出现在这里 "userRepo"

以上是要翻译的内容。

英文:

I have a stage issue. It looks completely correct to me but my IDE keeps showing me this error and will not compile.

  1. Cannot use 'userRepo' (type *UserRepo) as the type UserRepository Type does not
  2. implement 'UserRepository' need the method: GetByEmail(email string) (*User, error)
  3. have the method: GetByEmail(email string) (*User, error)

UserRepository.go

  1. type UserRepo struct {
  2. db *mongo.Client
  3. collection *mongo.Collection
  4. }
  5. func (m *UserRepo) GetByEmail(email string) (*User, error) {
  6. ctx := context.Background()
  7. var user *User
  8. err := m.collection.FindOne(ctx, bson.M{"username": email}).Decode(&user)
  9. if err != nil {
  10. return &User{}, err
  11. }
  12. return user, nil
  13. }
  14. func NewUserRepository(client *mongo.Client, collection *mongo.Collection) *UserRepo {
  15. return &UserRepo{
  16. db: client,
  17. collection: collection,
  18. }
  19. }

LoginService.go

  1. type Login struct {
  2. helper pkg.Helper
  3. user User
  4. res LoginResponse
  5. repo Repository
  6. userRepo UserRepository
  7. tokenRepo TokenRepository
  8. cfg config.Config
  9. validator *validator.Validator
  10. }
  11. type UserRepository interface {
  12. GetByEmail(email string) (*User, error)
  13. }
  14. func (l *Login) CreateAccountHandler(w http.ResponseWriter, r *http.Request) {
  15. .....
  16. _, err = l.userRepo.GetByEmail(email)
  17. // Check if the username is already taken.
  18. if err != nil {
  19. http.Error(w, "Username already taken", http.StatusConflict)
  20. json.NewEncoder(w).Encode(failedResponse)
  21. return
  22. }
  23. }
  24. func NewLoginService(repository Repository, tokenRepo TokenRepository, userRepo UserRepository) *Login {
  25. return &Login{
  26. helper: pkg.Helper{},
  27. repo: repository,
  28. userRepo: userRepo,
  29. tokenRepo: tokenRepo,
  30. validator: validator.New(),
  31. }
  32. }

The method names are the same and the type..

main.go

  1. // Login
  2. loginCollection := client.Database(cfg.MongoConfig.DBName).Collection(cfg.MongoConfig.LoginCollection)
  3. loginRepo := login.NewLoginRepository(client, loginCollection)
  4. usersCollection := client.Database(cfg.MongoConfig.DBName).Collection(cfg.UsersConfig.UserCollection)
  5. userRepo := data.NewUserRepository(client, usersCollection)
  6. loginService := login.NewLoginService(loginRepo, tokenRepo, userRepo) <----- error is here "userRepo"

答案1

得分: 4

根据代码中的描述:

  1. userRepo := data.NewUserRepository(client, usersCollection)
  2. loginService := login.NewLoginService(loginRepo, tokenRepo, userRepo)

NewUserRepository 函数位于 data 包中,所以 GetByEmail(email string) (*User, error) 中的 *Userdata.User 类型;而

NewLoginService 函数位于 login 包中,所以 UserRepository 接口中的 GetByEmail 中的 *Userlogin.User 类型。

data.Userlogin.User 是不同的类型,因此会出现错误。要纠正这个问题,可以修改函数或接口,使返回的类型来自同一个包。

英文:

Based on

  1. userRepo := data.NewUserRepository(client, usersCollection)
  2. loginService := login.NewLoginService(loginRepo, tokenRepo, userRepo)

NewUserRepository is in the package data so the *User in GetByEmail(email string) (*User, error) is a data.User whereas,

NewLoginService is in the package login so the *User in the GetByEmail within the UserRepository interface is a login.User.

data.User and login.User are different types hence the error. To correct this alter either the function or the interface such that the type returned is from the same package.

huangapple
  • 本文由 发表于 2023年7月29日 15:30:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/76792518.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定