在测试数据库方法时,我创建了一个包含数据库/ sql包的最小包装,以允许我测试接口而不是难以设置具体类。但是,我得到以下错误,当我尝试模拟sql.Stmt:在Go中嘲笑数据库/ sql结构
cannot use *sql.Stmt as type IStmt in return argument:
*sql.Stmt does not implement IStmt (wrong type for Query method)
have Query(...interface {}) (*sql.Rows, error)
want Query(...interface {}) (IRows, error)
这里是我的接口:
type IStmt interface {
Query(args ...interface{}) (IRows, error)
QueryRow(args ...interface{}) IRow
}
type IRows interface {
Columns() ([]string, error)
Next() bool
Close() error
Scan(dest ...interface{}) error
Err() error
}
和这里的问题方法:
func (c *DbConnection) Prepare(query string) (IStmt, error) {
return c.conn.Prepare(query)
}
我知道Go的优点之一就是可以创建自己的接口,任何实现它的结构都会自动“实现”它,而不必在java或us中使用implements
关键字e像C#中的分号子类。为什么它不使用这种返回类型?难道我做错了什么?
'* sql.Rows'没有实现'IStmt',所以你不能返回它。更改界面以返回具体类型(最快修复)。我还建议阅读[Effective Go](https://golang.org/doc/effective_go.html#interface-names)并查看你的界面命名(即'Queryer'或'Queryable')和/或阅读https ://robots.thoughtbot.com/interface-with-your-database-in-go – elithrar
但是* sql.Stmt实现了和我一样的Query方法和QueryRow方法。 Query(args ... interface {})(* Rows,error)'和'QueryRow(args ... interface {})* Row'。当然,我使用接口来表示'* sql.Rows'和'* sql.Row',但我使用的方法签名完全相同。如果我改变这些方法分别返回'* sql.Rows'和'* sql.Row',它就会起作用。如果Go无法处理返回类型的嵌套接口,那真是太遗憾了! –