译者:baiyutang
原文:https://bryanftan.medium.com/accept-interfaces-return-structs-in-go-d4cab29a301b
在这个文章中,我将试图解释 Golang “接受 Interfaces, 返回 Structs” 的思考过程。作为一名年轻的 Go 开发者,这是一直困扰我的事情。希望这篇文章能够帮助那些初学 Go 的人。
本文假设你对 Go 语法和接口已经很有初步的认识。
设定场景
生产者和消费者
├── db│ └── db.go└── user └── user.go
复制代码
接受 Interfaces
让使用者定义它要使用的接口
让我们看一个例子
//db.gopackage dbtype Store struct { db *sql.DB}func NewDB() *Store { ... } //func to initialise DBfunc (s *Store) Insert(item interface{}) error { ... } //insert itemfunc (s *Store) Get(id int) error { ... } //get item by id
复制代码
db.go 只提供写入和读取的方法。
//user.gopackage usertype UserStore interface { Insert(item interface{}) error Get(id int) error}type UserService struct { store UserStore}// Accepting interface here!func NewUserService(s UserStore) *UserService { return &UserService{ store: s, }}func (u *UserService) CreateUser() { ... }func (u *UserService) RetrieveUser(id int) User { ... }
复制代码
返回 Structs
生产者返回具体类型
在这个例子中,NewDB() 返回具体的类型给消费者
//db.gopackage dbtype Store struct { db *sql.DB}// returning concrete type here!func NewDB() *Store { ... }func (s *Store) Insert(item interface{}) error { ... }func (s *Store) Get(id int) error { ... }
复制代码
反例
现在我们看到了好的例子,我们转向一个普遍容易犯的反向的模式。
//postgres.gopackage db
type Store interface { Insert(item interface{}) error Get(id int) error}
type MyStore struct { db *sql.DB}
func InitDB() Store { ... } //func to initialise DBfunc (s *Store) Insert(item interface{}) error { ... } //insert itemfunc (s *Store) Get(id int) error { ... } //get item by id//user.gopackage user
type UserService struct { store db.Store}
func NewUserService(s db.Store) *UserService { return &UserService{ store: s, }}func (u *UserService) CreateUser() { ... }func (u *UserService) RetrieveUser(id int) User { ... }
复制代码
总结
“接受 Interfaces,返回 Structs ”,当你第一次听这个,可能听起来如此的不相关。但是,它可以归纳为这两个主要的概念:
让消费者定义他用到的 Interfaces
生产者应该返回一个具体的类型
附加资料
评论