You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用db.QueryRow时触发Golang运行时空指针引用错误求助

解决Go TodoList项目中的空指针运行时错误

问题根源分析

从错误栈和代码来看,空指针错误由两个核心问题导致:

1. 数据库连接变量被遮蔽且提前关闭

在db.go的InitDatabase函数中,使用:=声明了局部变量Conn,直接覆盖了全局定义的var Conn *pgx.Conn,导致全局Conn始终为nil。同时,函数内的defer Conn.Close()会在函数执行完毕后立即关闭连接,后续请求无法获取有效数据库连接。

2. Task指针未初始化

在controller.go的GetTasks函数中,response是未初始化的*Task类型指针,直接访问&response.Title会触发空指针解引用错误。


修复方案

修复数据库连接问题(db.go)

修改InitDatabase函数,避免变量遮蔽,移除提前关闭连接的逻辑:

package db

import (
    "os"
    "fmt"
    "context"

    "github.com/jackc/pgx/v4"
    "github.com/fishkaoff/todoList/internal/config"
)

var Conn *pgx.Conn

func InitDatabase(config config.Config) {
    var err error
    // 使用=赋值给全局变量,而非:=创建局部变量
    Conn, err = pgx.Connect(context.Background(), config.DBUrl)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Unable to connect to database: %v\n", err)
        os.Exit(1)
    }
    // 移除defer Conn.Close(),避免连接被提前关闭
}

同时在main.go中添加程序退出时的连接关闭逻辑:

func main() {
    // ... 其他初始化逻辑
    db.InitDatabase(cfg)
    defer db.Conn.Close() // 程序退出时统一关闭连接
    // ... 启动gin服务等逻辑
}

修复Task指针初始化问题(controller.go)

将response声明为值类型或提前初始化指针:

func GetTasks(c *gin.Context) {
    // 方案1:使用值类型(推荐)
    var response Task
    // SQL明确指定列名,避免表结构变更导致字段不匹配
    err := db.Conn.QueryRow(context.Background(), "select title, description from tasks").Scan(&response.Title, &response.Description)
    
    // 方案2:初始化指针
    // response := &Task{}
    // err := db.Conn.QueryRow(...).Scan(&response.Title, &response.Description)

    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
        return // 错误时终止后续逻辑
    }

    c.JSON(http.StatusOK, gin.H{
        "page":  "gettasks",
        "tasks": response,
    })
}

内容的提问来源于stack exchange,提问作者fishkaoff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 14:15:31