所以我有一个需要在整个软件包中共享的SQL指针(*sql.DB
)。
例如:
" ./main.go
"有一个全局变量" db
"需要与" ./another/package.go
"。中的包共享
如何在不传递函数参数的情况下实现共享变量?
答案 0 :(得分:3)
只要导出全局变量(意味着其名称以大写字母开头:Db *sql.DB
),您就可以通过其全名在另一个包中访问它:
package.name.Db
但全局变量的替代方法是依赖注入,就像使用inject framework初始化正确的数据库一样。
请参阅“Dependency Injection with 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
}
答案 1 :(得分:0)
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
应该只是其他包的入口点,并且应该尽量避免自己消费。