【问题标题】:Golang, Pointers, FunctionsGolang,指针,函数
【发布时间】:2017-02-16 22:22:20
【问题描述】:

我对 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() 中时,查询有效 - 我假设这是因为函数具有“本地”范围(这是正确的术语吗?),我需要将 db 对象定义为我在主要功能。

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

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

谢谢

【问题讨论】:

  • db 作为参数传递给q() 怎么样?那会起作用的。
  • 这也不适用于 python 范围规则,您在 main 中定义了 db,但试图在 q 中引用它。
  • 你的假设和术语是完全正确的,同样的事情在 python 中也行不通。
  • 我认为你需要先安装插件来检查你的代码错误。那里有很棒的编辑器和插件。

标签: pointers go scope


【解决方案1】:

db var 定义在 main func 范围内,因此您的 q func 不会“看到”它。您必须作为指向 q 方法的指针传递。类似的东西:

func q(db *sql.DB) {
   ...
}

main 中的 db var 已经是指向 sql.DB 结构的指针,因此您只需在 main func 中调用 q(db) 即可。

【讨论】:

  • 继续!你做得很好! Go 对你来说是一个新世界,所以在第一次尝试时感到困惑是正常的
  • 请去掉“引用”这个词:Go 中没有引用。
【解决方案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
    )
.
.
.
.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-22
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    • 1970-01-01
    • 2014-10-12
    • 2014-02-20
    • 2014-01-10
    相关资源
    最近更新 更多