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

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

问题描述

我有以下文件结构:

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")
    }
}

当我尝试访问 InsertProfile 函数中的 db 时,它显示 NULL ptr exception.如何访问 db_utils.go 中的 db?

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

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

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

我正确地从 init() 中的 db 返回了 QUERY.

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

推荐答案

问题是你使用了 短变量声明 := 并且您只是将创建的 *DB 值存储在局部变量中而不是全局变量中.

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.

这一行:

db, err := NewDB(dbinfo)

创建2个局部变量:dberr,这个局部db和你的全局db无关代码>变量.您的全局变量将保持 nil.您必须将创建的 *DB 分配给全局变量.不要使用简短的变量声明,而是使用简单的赋值,例如:

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)
}

原始答案如下.

它是一个指针类型,使用前必须初始化.指针类型的零值是 nil.

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.

一个好的解决方案是在自动调用的包 init() 函数中执行此操作.

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

请注意,sql.Open() 可能只需验证其参数,而无需创建与数据库的连接.要验证数据源名称是否有效,请调用 DB.Ping().

例如:

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天全站免登陆