Golang,指针,功能

时间:2017-02-16 22:22:21

标签: pointers go scope

我是Golang的新手,也是一般编译的静态类型编程。我之前的所有经验都是使用Python。

这种范式转变既令人沮丧(程序很少编译)又有回报,因为我终于了解了许多以前对我来说很陌生的概念(垃圾收集,指针,范围)。

有人可以在概念层面向我解释为什么这个程序无法编译以及修复它的语法?我只是试图查询数据库并打印结果:

package main

import (
    "database/sql"
    "log"

    _ "github.com/denisenkom/go-mssqldb"
)

func main() {

    db, err := sql.Open("sqlserver", "odbc:server=myServer;user id=myName;password=myPassword;")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    q()
}

func q() {

    var (
        id   int
        name string
    )

    rows, err := db.Query("SELECT id, name FROM myTable")
    if err != nil {
        log.Fatal(err)
    }
    defer rows.Close()

    for rows.Next() {
        err := rows.Scan(&id, &name)

        if err != nil {
            log.Fatal(err)
        }
        log.Println(id, name)
    }
    err = rows.Err()
    if err != nil {
        log.Fatal(err)
    }

}

我得到的错误是:

undefined: db in db.Query

当我将q()中的逻辑放在main函数中时,查询有效 - 我假设这是因为函数具有“本地”范围(是正确的术语吗?)并且我需要将db对象定义为我有主要功能。

如果是这种情况 - 如何在不重复建立数据库连接的情况下运行q()函数?这是“指针”的来源吗?另外,我还不确定&符号在这里做了什么:

 err := rows.Scan(&id, &name)

由于

2 个答案:

答案 0 :(得分:3)

QOpenGLBuffer var在db功能范围定义,因此您的main功能不会在"""它。您必须作为指针传递给q方法。这样的事情:

q

func q(db *sql.DB) { ... } db中的main变量已经是指向sql.DB结构的指针,因此您只需在q(db) func中进行main调用即可39;工作。

答案 1 :(得分:2)

正如其他人提到的,问题是变量db在函数main中声明,并且您正试图在q函数中访问该变量。您有两种方法可以解决此问题:

1)将变量db声明为主函数之外的全局变量,如下所示:

正如其他人提到的,问题是变量db在函数main中声明,并且您正试图在q函数中访问该变量。您有两种方法可以解决此问题:

1)将变量db声明为主函数之外的全局变量,如下所示:

package main

import (
"database/sql"
"log"
_ "github.com/denisenkom/go-mssqldb"
)

var db *sql.DB

func main() {

db, err = sql.Open("sqlserver", "odbc:server=myServer;user id=myName;password=myPassword;")
.
.
.
.

需要注意的重要事项是赋值(=而不是:=)运算符用于为全局变量赋值。因为如果您使用短变量声明:=,那么它将创建一个本地db变量。

2)您可以将db指针作为参数传递给函数q,如下所示:

package main

import (
    "database/sql"
    "log"
    _ "github.com/denisenkom/go-mssqldb"
)
func main() {

    db, err := sql.Open("sqlserver", "odbc:server=myServer;user id=myName;password=myPassword;")
    if err != nil {
      log.Fatal(err)
    }
    defer db.Close()

    q(db)
}

func q(db *sql.DB) {

    var (
        id   int
        name string
    )
.
.
.
.