But why? Why exactly we need this and what struct implementation is not enough and we need interface? Can you please give me a good example demo so that I can understand it properly. Thanks.
Interfaces are great if you have different implementations. For example:
type Repo interface {
MyFunc()
MyAnotherFunc()
}
type SQLRepo struct {
Db *gorm.DB
}
func (repo SQLRepo) MyFunc() {}
func (repo SQLRepo) MyAnotherFunc() {}
type MongoDBRepo struct {
client *mongo.Client
}
func (repo MongoRepo) MyFunc() {}
func (repo MongoRepo) MyAnotherFunc() {}
func NewRepo(connectionString string) (Repo, error) {
switch {
case strings.HasPrefix(connectionString, "mongodb://"):
return &MongoRepo{mongodb.Connect(/* ... */)}, nil
case strings.HasPrefix(connectionString, "sql://"):
return &SQLRepo{/* ... */}, nil
}
return nil, fmt.Errorf("implementation cannot be determined by connectionString")
}
func main() {
// parse arguments or a config file or something
repo, err := NewRepo(config.ConnectionString)
// now you can use repo and not care if it's backed by SQL
// or MongoDB, etc.
}