无法将查询数据扫描至变量,打印User结构体为空求排查
问题分析与解决
你的代码打印出空结构体,核心原因有两个:
1. 标准库database/sql的Scan不支持直接扫描结构体
Go标准库database/sql的Scan方法仅接受单个字段的指针作为参数,无法直接将查询结果映射到结构体实例。直接传递&u会导致扫描失败,但此时错误尚未被捕获,你先打印了未赋值的初始空结构体。
2. 错误处理顺序颠倒
代码中先打印u再判断err,即便扫描过程中出现错误(比如无匹配数据、字段不匹配),你看到的依然是初始空结构体,无法通过错误信息定位问题。
解决办法
方法一:标准库逐个字段扫描
明确指定查询字段,将每个字段的指针传入Scan,确保字段顺序与查询语句完全一致:
type User struct { Username string `db:"username"` Email string `db:"email"` Password string `db:"password"` } func SearchUserInDB(db *sql.DB, userormail string) error { var u User // 避免使用SELECT *,明确指定字段,保证与Scan参数顺序匹配 err := db.QueryRow(` SELECT username, email, password FROM users WHERE username = $1`, userormail).Scan(&u.Username, &u.Email, &u.Password) // 先判断错误,再使用变量 if err != nil { return err } fmt.Println(u) return nil }
方法二:用ORM扩展库简化结构体扫描
若需频繁映射结构体,推荐使用sqlx这类扩展库,它支持通过结构体标签自动映射字段:
// 先安装sqlx:go get github.com/jmoiron/sqlx import "github.com/jmoiron/sqlx" func SearchUserInDB(db *sqlx.DB, userormail string) error { var u User err := db.QueryRowx(` SELECT * FROM users WHERE username = $1`, userormail).StructScan(&u) if err != nil { return err } fmt.Println(u) return nil }
额外注意事项
- 禁止使用
SELECT *,明确指定字段可避免表结构变更导致的字段顺序错位问题。 - 错误处理必须优先于变量使用,否则初始值会干扰调试。
内容的提问来源于stack exchange,提问作者nidstang
相关产品推荐
相关产品推荐

