我有两个函数接受指向不同结构的不同指针,但结构具有相同的底层函数。
func Save(db *sql.DB) error {
db.Prepare(query)
}
func TxSave(tx *sql.Tx) error {
tx.Prepare(query)
}
我不想在将来需要扩展此功能时对这两个功能进行更改。如何在这种情况下坚持golang中的DRYness?
创建一个界面,例如:
type SQLRunner interface{
Prepare(query string) (*sql.Stmt, error)
PrepareContext(ctx context.Context, query string) (*sql.Stmt, error)
Query(query string, args ...interface{}) (*Rows, error)
QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
// add as many method shared by both sql.Tx qnd sql.DB
// ...
}
然后创建一个采用该接口的方法:
func Save(s SQLRunner) error {
s.Prepare()
}
在go接口实现是隐式的,所以你只需要将* sql.Tx或* sql.DB传递给save函数:
Save(tx)
Save(db)
这里有一篇关于go:http://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go中接口的好文章
哇,我想我爱上了Go。我实际上可以通过创建自己的界面来做到这一点。
type Saver interface {
Prepare(query string) (*sql.Stmt, error)
}
func Save(db *sql.DB) error {
return GenericSave(db)
}
func TxSave(tx *sql.Tx) error {
return GenericSave(tx)
}
func GenericSave(saver Saver) error {
stmt := saver.Prepare(query)
// Do rest with saver
}