gpt4 book ai didi

go - 在 GO 中重用数据库连接和 'invalid memory address' 错误

转载 作者:IT王子 更新时间:2023-10-29 01:49:43 24 4
gpt4 key购买 nike

我是 GO 的新手,似乎找不到任何关于在全局中重用数据库连接的错误信息。这是导致错误的代码的简化版本:

主要包

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

var debug = flag.Bool("debug", false, "enable debugging")
var password = flag.String("password", "*****", "the database password")
var port *int = flag.Int("port", 1433, "the database port")
var server = flag.String("server", "localhost", "the database server")
var user = flag.String("user", "*****", "the database user")
var db *sql.DB

func main() {
// Parse the incoming flags to set variables.
flag.Parse()

// Output the database variables if the debug flag is set.
if *debug {
fmt.Printf(" password:%s\n", *password)
fmt.Printf(" port:%d\n", *port)
fmt.Printf(" server:%s\n", *server)
fmt.Printf(" user:%s\n", *user)
}

// Build out the connection string to the database, and then open the connection to the database.
connString := fmt.Sprintf("server=%s;user id=%s;password=%s;port=%d", *server, *user, *password, *port)
if *debug { fmt.Printf(" connString:%s\n", connString) }
db, err := sql.Open("mssql", connString)
if err != nil { log.Fatal("Open connection failed:", err.Error()) }
err = db.Ping()
if err != nil {
fmt.Println("Cannot connect: ", err.Error())
return
}

// Close the connection when we're all done.
defer db.Close()

// Truncate the existing records in the ListHubFeed
res, err := db.Exec( `
TRUNCATE TABLE foo
` )
_ = res

if err != nil {
fmt.Println( "TRUNCATE TABLE failed", err )
}

eligible := verifyEligibility( "foo" )

}

func verifyEligibility( email string ) ( success bool ) {

//Run each check individually, and if any one fails, return false and stop processing additional checks

// if the routing email is bad, then we can't create an account, so kick it out.
if( !govalidator.IsEmail( email ) ){
writeToLog( email )
return false
}

return true;

}

func writeToLog( tolog string ) {
res, err := db.Exec(`
INSERT INTO Log (
Email
) VALUES (
?,
?,
?,
?
)` , tolog )
if err != nil {
fmt.Println( "insert failed", err )
}
_ = res
}

那是非常丑陋的伪代码,但重点是 main 中的 TRUNCATE 语句运行得很好,但是在调用 verifyEligibility() 和然后尝试在 writeToLog() 函数中记录条目,我收到以下错误:

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x1 addr=0x0 pc=0x46d485]

goroutine 1 [running]:
database/sql.(*DB).conn(0x0, 0xc082044088, 0x0, 0x0)
c:/go/src/database/sql/sql.go:634 +0x7b5
database/sql.(*DB).exec(0x0, 0x742730, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
c:/go/src/database/sql/sql.go:884 +0x9d
database/sql.(*DB).Exec(0x0, 0x742730, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
c:/go/src/database/sql/sql.go:875 +0xd4
main.writeToLog(0xc082004a20, 0x11, 0x70f370, 0x5, 0x0, 0x0, 0x777ef0, 0x24, 0x71ba70, 0x3)

我找不到关于此错误的任何信息,因为它与 go-mssqldb 相关。 db 被声明为全局的,并在 main 中打开,所以我不明白为什么它在 writeToLog() 中对我不可用>.

最佳答案

您的问题是 db 指针在 writeToLog() 函数的上下文中为 nil。罪魁祸首是这一行:

db, err := sql.Open("mssql", connString)

在这里,您将短变量声明运算符 (:=) 与赋值运算符 (=) 混淆了。

此指令使用 db 局部变量覆盖 db 全局变量,只能在您的 main 函数中访问(这称为 阴影,也可以使用包名等)。因此,writeToLog 中使用的 db 变量从未被初始化,因此出现了 nil pointer dereference 错误。

要修复它,您只需修复您的声明,使其成为一种矫揉造作:

var err error
db, err = sql.Open("mssql", connString)

关于go - 在 GO 中重用数据库连接和 'invalid memory address' 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28965092/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com