如何在包中的文件中使用全局变量? [英] How to use global var across files in a package?

查看:213
本文介绍了如何在包中的文件中使用全局变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下文件结构:

models / db.go

  type DB struct {
* sql.DB
}

var db * DB

func init (){
dbinfo:= fmt.Sprintf(user =%s password =%s dbname =%s sslmode = disable,
DB_USER,DB_PASSWORD,DB_NAME)

db,err:= newDB(dbinfo)
checkErr(err)
$ b行,err:= db.Query(SELECT * FROM profile)
checkErr(err)

fmt.Println(rows)
}

func NewDB(dataSourceName string)(* DB,error){$ b $ db,err:= sql。打开(postgres,dataSourceName)
if err!= nil {
return nil,err
}
if err = db.Ping(); err!= nil {
return nil,err
}
return& DB {db},nil
}

models / db_util.go

  func(p * Profile)InsertProfile(){
if db!= nil {
_,err:= db.Exec(...)
checkErr(err)
} else {
fmt.Println(DB object is NULL)
}
}

当我尝试访问 InsertProfile 函数中的 db 时,它表示 NULL ptr异常。如何访问 db_utils.go 中的 db



我不想大写 db (因为它可以访问所有的包)。



I正确地获取从 db init()中返回的QUERY。

解决方案

编辑:问题是您使用短变量声明 := ,并且只是将创建的 * DB 值存储在一个局部变量,而不是全局变量。



这行:

  db,err:= NewDB(dbinfo)

创建2个局部变量: db err ,并且这个本地 db 与您的全局 db 变量。您的全局变量将保持 nil 。您必须将创建的 * DB 分配给全局变量。不要使用简短的变量声明,而要使用简单的作业,例如:

  var err错误
db,err = NewDB(dbinfo)
if err!= nil {
log.Fatal(err)
}

原始答案如下。






这是一个指针类型,您必须在使用它之前对它进行初始化。指针类型的零值是 nil

您不必导出它(这是以大写字母开头的内容)。请注意,只要它们是同一个软件包的一部分,就可以访问多个文件并不重要,它们可以访问彼此定义的标识符。



一个好的解决方案会在 init()函数中自动调用它。



请注意 sql.Open() 可能只是验证它的参数没有建立到数据库的连接。要验证数据源名称是否有效,请致电 DB.Ping ()



例如:

  var db * sql.DB 

func init(){
var err error $ b $ db,err = sql.Open(yourdrivername,somesource )
if err!= nil {
log.Fatal(err)
}
if err = db.Ping(); err!= nil {
log.Fatal(err)
}
}


I have the following file structure:

models/db.go

type DB struct {
    *sql.DB
}

var db *DB

func init() {
    dbinfo := fmt.Sprintf("user=%s password=%s dbname=%s sslmode=disable",
        DB_USER, DB_PASSWORD, DB_NAME)

    db, err := NewDB(dbinfo)
    checkErr(err)

    rows, err := db.Query("SELECT * FROM profile")
    checkErr(err)

    fmt.Println(rows)
}

func NewDB(dataSourceName string) (*DB, error) {
    db, err := sql.Open("postgres", dataSourceName)
    if err != nil {
        return nil, err
    }
    if err = db.Ping(); err != nil {
        return nil, err
    }
    return &DB{db}, nil
}

models/db_util.go

func (p *Profile) InsertProfile() {
    if db != nil {
        _, err := db.Exec(...)
        checkErr(err)
    } else {
        fmt.Println("DB object is NULL")
    }
}

When I try to access db in InsertProfile function, it says NULL ptr exception. How do I access the db in db_utils.go?

I would not like to capitalize db (as it would give access to all the packages).

I am getting the QUERY returned from the db in init() correctly.

解决方案

Edit: The problem is that you used Short variable declaration := and you just stored the created *DB value in a local variable and not in the global one.

This line:

db, err := NewDB(dbinfo)

Creates 2 local variables: db and err, and this local db has nothing to do with your global db variable. Your global variable will remain nil. You have to assign the created *DB to the global variable. Do not use short variable declaration but simple assignment, e.g:

var err error
db, err = NewDB(dbinfo)
if err != nil {
    log.Fatal(err)
}

Original answer follows.


It's a pointer type, you have to initialize it before you use it. The zero value for pointer types is nil.

You don't have to export it (that's what starting it with a capital letter does). Note that it doesn't matter that you have multiple files as long as they are part of the same package, they can access identifiers defined in one another.

A good solution would be to do it in the package init() function which is called automatically.

Note that sql.Open() may just validate its arguments without creating a connection to the database. To verify that the data source name is valid, call DB.Ping().

For example:

var db *sql.DB

func init() {
    var err error
    db, err = sql.Open("yourdrivername", "somesource")
    if err != nil {
        log.Fatal(err)
    }
    if err = db.Ping(); err != nil {
        log.Fatal(err)
    }
}

这篇关于如何在包中的文件中使用全局变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆