go之如何使用接口(interface)在 Golang 中为数据库实现依赖注入(inject)

exmyth 阅读:204 2025-06-02 22:19:02 评论:0

我有以下代码尝试使用数据库实现依赖注入(inject),以便稍后在测试中模拟它。

问题是编译器无法识别 db 作为实现接口(interface):cannot use db (type *sqlx.DB) as type storage in field value: *sqlx.DB does not implement storage .

package main 
 
func main() { 
    db, _ := database.NewDB() 
 
    api, _ := controllers.NewAPI(db) 
    api.Register(data) 
} 

Controller /main.go
package controllers 
 
type storage interface { 
    AccountExists(id int64) 
} 
 
type API struct { 
    storage 
} 
 
func NewAPI(db *sqlx.DB) (*API, error) { 
    return &API{db}, nil 
} 
 
func (api *API) Register(userdata) { 
    // register user here 
} 

存储/数据库.go
package database 
 
func NewDB() (*sqlx.DB, error) { 
    // connect to db ere 
    return database, nil 
} 
 
type DB struct { 
    *sqlx.DB 
} 
 
func (db *DB) Account(id int64) (bool, error) { 
    // query db here 
} 

我试过实现类型 DBcontrollers , 但如果我不在 database 中声明它我不能在那里定义它的方法,如果我在两者中都声明它,编译器将不会将它识别为实现接口(interface)。我想我已经接近实现这一点,但我真的尝试了所有我能想到的。

请您参考如下方法:

您走在正确的轨道上,但是与接口(interface)相关的代码中存在一些错误。

为了让结构实现您的 storage接口(interface)它需要有一个带有签名的方法AccountExists(id int64) .根据规范 ( https://godoc.org/github.com/jmoiron/sqlx#DB ) sqlx.Db没有具有此签名的方法。

你需要做的是这样的:

package database 
 
func NewMyDB() (*MyDB, error) { 
    dbConnection := // get an *sqlx.DB instance 
    return &MyDB{db: dbConnection}, nil 
} 
 
type MyDB struct { 
    db *sqlx.DB 
} 
 
func (db *MyDB) AccountExists(id int64) { 
    // query db here 
} 

Controller :
type storage interface { 
    AccountExists(id int64) 
} 
 
type API struct { 
    db storage 
} 
 
func NewAPI(db storage) (*API, error) { 
    return &API{db}, nil 
} 

注意几件事。 1.以前你的 NewMyDB构造函数返回 sqlx.DB 的实例而不是结构的实例(我将其重命名为 MyDB 以避免与 sqlx.DB 类混淆)。 2.以前你的 MyDB struct 没有带有签名 AccountExists(id int64) 的方法.因此它没有实现 storage因为 storage需要这个方法。

我建议阅读一些关于接口(interface)如何在 Golang 中工作的内容。我认为这对解决您的问题有很大帮助。这是一个您可以快速阅读的链接(其中包括另一个链接,指向更长但有用的博客文章): https://gobyexample.com/interfaces


标签:数据库
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号