在整个包中共享一个全局变量
Sharing a global variable throughout packages
所以我有一个 SQL 指针 (*sql.DB
) 需要在整个包中共享。
例如:
"./main.go
" 有一个全局变量 "db
" 需要与 "./another/package.go
" 中的包共享。
不传函数参数怎么实现共享变量?
只要导出了全局变量(意思是它的名字以大写字母开头:Db *sql.DB
),你可以通过它的全名在另一个包中访问它:
package.name.Db
但全局变量的替代方法是依赖注入,如使用 inject framework 初始化正确的数据库。
参见“Dependency Injection with Go”:
The inject
library is the result of this work and our solution.
It uses struct
tags to enable injection, allocates memory for concrete types, and supports injection for interface types as long as they’re unambiguous.
It also has some less often used features like named injection. Roughly, our naive example above now looks something like this:
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
}
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
}
使用构造函数来初始化包的要求通常是一种很好的做法,and/or 传递预初始化的对象 - 例如datastore.NewFromExisting(db)
传入您已经创建的池。
在可能的情况下,您的 package main
应该只是其他包的入口点,并且应该尽量避免自己消耗东西。
所以我有一个 SQL 指针 (*sql.DB
) 需要在整个包中共享。
例如:
"./main.go
" 有一个全局变量 "db
" 需要与 "./another/package.go
" 中的包共享。
不传函数参数怎么实现共享变量?
只要导出了全局变量(意思是它的名字以大写字母开头:Db *sql.DB
),你可以通过它的全名在另一个包中访问它:
package.name.Db
但全局变量的替代方法是依赖注入,如使用 inject framework 初始化正确的数据库。
参见“Dependency Injection with Go”:
The
inject
library is the result of this work and our solution.
It usesstruct
tags to enable injection, allocates memory for concrete types, and supports injection for interface types as long as they’re unambiguous.
It also has some less often used features like named injection. Roughly, our naive example above now looks something like this:
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
}
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
}
使用构造函数来初始化包的要求通常是一种很好的做法,and/or 传递预初始化的对象 - 例如datastore.NewFromExisting(db)
传入您已经创建的池。
在可能的情况下,您的 package main
应该只是其他包的入口点,并且应该尽量避免自己消耗东西。