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

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

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

问题

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

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

UserRepository.go

type UserRepo struct {
	db         *mongo.Client
	collection *mongo.Collection
}

func (m *UserRepo) GetByEmail(email string) (*User, error) {

	ctx := context.Background()

	var user *User
	err := m.collection.FindOne(ctx, bson.M{"username": email}).Decode(&user)
	if err != nil {
		return &User{}, err
	}

	return user, nil
}

func NewUserRepository(client *mongo.Client, collection *mongo.Collection) *UserRepo {
	return &UserRepo{
		db:         client,
		collection: collection,
	}
}

LoginService.go

type Login struct {
	helper    pkg.Helper
	user      User
	res       LoginResponse
	repo      Repository
	userRepo  UserRepository
	tokenRepo TokenRepository
	cfg       config.Config
	validator *validator.Validator
}

type UserRepository interface {
	GetByEmail(email string) (*User, error)
}

func (l *Login) CreateAccountHandler(w http.ResponseWriter, r *http.Request) {

	......

	_, err = l.userRepo.GetByEmail(email)
	// Check if the username is already taken.
	if err != nil {
		http.Error(w, "Username already taken", http.StatusConflict)

		json.NewEncoder(w).Encode(failedResponse)
		return
	}
}

func NewLoginService(repository Repository, tokenRepo TokenRepository, userRepo UserRepository) *Login {
	return &Login{
		helper:    pkg.Helper{},
		repo:      repository,
		userRepo:  userRepo,
		tokenRepo: tokenRepo,
		validator: validator.New(),
	}
}

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

main.go

// Login
loginCollection := client.Database(cfg.MongoConfig.DBName).Collection(cfg.MongoConfig.LoginCollection)
loginRepo := login.NewLoginRepository(client, loginCollection)
usersCollection := client.Database(cfg.MongoConfig.DBName).Collection(cfg.UsersConfig.UserCollection)
userRepo := data.NewUserRepository(client, usersCollection)
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.

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

UserRepository.go

type UserRepo struct {
	db         *mongo.Client
	collection *mongo.Collection
}


func (m *UserRepo) GetByEmail(email string) (*User, error) {

	ctx := context.Background()

	var user *User
	err := m.collection.FindOne(ctx, bson.M{"username": email}).Decode(&user)
	if err != nil {
		return &User{}, err
	}

	return user, nil
}

func NewUserRepository(client *mongo.Client, collection *mongo.Collection) *UserRepo {
	return &UserRepo{
		db:         client,
		collection: collection,
	}
}

LoginService.go

type Login struct {
	helper    pkg.Helper
	user      User
	res       LoginResponse
	repo      Repository
	userRepo  UserRepository
	tokenRepo TokenRepository
	cfg       config.Config
	validator *validator.Validator
}

type UserRepository interface {
	GetByEmail(email string) (*User, error)
}

func (l *Login) CreateAccountHandler(w http.ResponseWriter, r *http.Request) {
	
    .....

	_, err = l.userRepo.GetByEmail(email)
	// Check if the username is already taken.
	if err != nil {
		http.Error(w, "Username already taken", http.StatusConflict)

		json.NewEncoder(w).Encode(failedResponse)
		return
	}
}

func NewLoginService(repository Repository, tokenRepo TokenRepository, userRepo UserRepository) *Login {
	return &Login{
		helper:    pkg.Helper{},
		repo:      repository,
		userRepo:  userRepo,
		tokenRepo: tokenRepo,
		validator: validator.New(),
	}
}

The method names are the same and the type..

main.go

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

答案1

得分: 4

根据代码中的描述:

userRepo := data.NewUserRepository(client, usersCollection)
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

userRepo := data.NewUserRepository(client, usersCollection)
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:

确定