Golang数据库连接错误如何解决
Golang数据库连接错误如何解决 我的文件结构是:
- main.go
- config —db.go
在db.go文件中,我将程序与数据库连接
package config
import (
"database/sql"
_ "github.com/lib/pq"
"fmt"
)
var Db *sql.DB
func init() {
Db, err := sql.Open("postgres",
"postgres://postgres:Yfehsp2203@localhost/postgres?sslmode=disable")
if err != nil {
panic("Can not connect to DB")
}
if err = Db.Ping(); err != nil {
panic("Pingin error")
}
fmt.Println("Successfully connected")
}
它连接正常,但是当我在main.go中尝试访问数据库时
if err := config.Db.Ping(); err != nil {
panic("Pingin error")
}
fmt.Println("DATABASE IS ON")
只是进行ping操作就会出现大量错误,我不明白为什么,请帮忙!!!
更多关于Golang数据库连接错误如何解决的实战教程也可以访问 https://www.itying.com/category-94-b0.html
很好,现在可以正常工作了,但你能解释一下原因吗?"shadowed"是什么意思?
Db 在 init() 中被遮蔽了:
Db, err := sql.Open("postgres",
"postgres://postgres:Yfehsp2203@localhost/postgres?sslmode=disable")
避免遮蔽 Db,并通过以下方式赋值给全局 Db:
var err error
Db, err = sql.Open("postgres",
"postgres://postgres:Yfehsp2203@localhost/postgres?sslmode=disable")
:= 会在当前作用域内创建其左侧不存在的变量。该行的当前作用域是 init() 函数。由于在 init()(当前作用域)中之前没有声明过 Db,因此 Db 是由 := 创建的(连同 err 一起)。
改用 = 需要先声明 err(否则会出现未声明的变量)。然后 Go 可以通过首先在当前作用域 init() 中查找,未找到 Db,然后在当前作用域的父级(全局作用域)中查找,从而找到全局的 Db,Db 是在全局作用域中声明的。
变量遮蔽是指当前作用域中的变量掩盖/阻止/阻止访问父作用域中同名的变量。
有关带有示例代码的更长解释,请参阅 Go 中的作用域与变量遮蔽。
问题出在变量作用域上。在db.go的init()函数中,你使用了短变量声明:=重新声明了Db变量,这创建了一个新的局部变量,而不是给包级别的var Db *sql.DB赋值。
以下是修复后的代码:
config/db.go:
package config
import (
"database/sql"
"fmt"
_ "github.com/lib/pq"
)
var Db *sql.DB
func init() {
var err error
// 使用赋值操作,而不是短变量声明
Db, err = sql.Open("postgres",
"postgres://postgres:Yfehsp2203@localhost/postgres?sslmode=disable")
if err != nil {
panic("Can not connect to DB")
}
if err = Db.Ping(); err != nil {
panic("Pingin error")
}
fmt.Println("Successfully connected")
}
main.go:
package main
import (
"fmt"
"your-module-name/config"
)
func main() {
// 现在应该能正常工作了
if err := config.Db.Ping(); err != nil {
panic("Pingin error")
}
fmt.Println("DATABASE IS ON")
}
关键修改:
- 将
Db, err := sql.Open(...)改为Db, err = sql.Open(...) - 提前声明
var err error - 确保模块导入路径正确
这样包级别的Db变量就会被正确初始化,在main.go中就可以正常访问了。

