2 回答
TA贡献1884条经验 获得超4个赞
只要全局变量被导出(意思是它的名字以大写字母: 开头Db *sql.DB),你就可以通过它的全名在另一个包中访问它:
package.name.Db
但是全局变量的替代方案是依赖注入,就像使用注入框架来初始化正确的数据库一样。
参见“使用 Go 进行依赖注入”:
该inject库是这项工作和我们的解决方案的结果。
它使用struct标签来启用注入,为具体类型分配内存,并支持接口类型的注入,只要它们是明确的。
它还具有一些不太常用的功能,例如命名注入。粗略地说,我们上面的简单示例现在看起来像这样:
type AppLoader struct {
MongoService mongo.Service `inject:""`
}
func (l *AppLoader) Get(id uint64) *App {
a := new(App)
l.MongoService.Session().Find(..).One(a)
return a
}
TA贡献1871条经验 获得超8个赞
VonC 问题的替代方法是提供一个构造函数 - 例如
// package datastore
var db *sql.DB
func NewDB(host, port string) (*sql.DB, error) {
// Simplified example
conn, err := sql.Open(...)
if err != nil {
return nil, err
}
db = conn
return conn, nil
}
// package main
func main() {
db, err := datastore.NewDB("localhost", "5432")
if err != nil {
log.Fatal(err)
}
// Now you can use it here, and/or in your datastore package
}
使用构造函数来初始化包的要求和/或传入预初始化的对象通常是一种很好的做法 - 例如datastore.NewFromExisting(db)传入你已经创建的池。
在可能的情况下,您package main应该只是其他包的入口点,并应尽量避免自己使用东西。
- 2 回答
- 0 关注
- 150 浏览
添加回答
举报