在各个包之间共享全局变量

3

我有一个SQL指针(*sql.DB),需要在各个包之间共享。

例如:

"./main.go" 有一个全局变量 "db",需要与 "./another/package.go" 中的一个包共享。
如何在不传递函数参数的情况下实现变量共享呢?

2个回答

3
只要全局变量被导出(也就是说,它的名称以大写字母开头:Db *sql.DB),你就可以通过其完整名称在另一个包中访问它。
package.name.Db

但是,全局变量的替代方案是依赖注入,比如使用inject框架来初始化正确的数据库。

参见 "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
}

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应该只是其他软件包的入口点,并尽量避免自己消耗东西。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接