Argument and Return types on interface implementation

Viewed 171

Should the methods of the implementation of an Interface accept and return interfaces or can they be types? Let me explain:

type Record interface {
	Pk() any
}
type Repository interface {
	Add(Record) error
	Get(string) (*Record, error)
}

And implementations:

type UserRecord struct {
	Id    string
}
func (record *UserRecord) Pk() any {
	return record.Id
}

type SqlUserRepository struct {
	Db *sql.DB
}
····

Since UserRecord implements Record, and SqlUserRepository is only expected to treat with UserRecord structs, Which would be the correct design decision?

func (repo *SqlUserRepository) Add(record Record) error {}
func (repo *SqlUserRepository) Add(record *UserRecord) error {}

In case of using record I convert record to UserRecord and return some error if !ok

EDIT

So now I have a problem. When using SqlUserRepository I will do things like:

user := repo.Get("asbhjs")

and user it's going to be of type Record, so now I have to convert it to UserRecord again to be able to acces it's fields. Converting back and forth Record to UserRecord seems like there is a design flaw, how could I avoid this?

1 Answers

Ok, my bad, I don't know why I thought that was possible, it's not. The same IDE complains.

So yea, it has to use the same interface/type as stated in the Interface and then do a type conversion.