Go pq QueryRow扫描失败,内存地址无效或无指针取消引用
我有以下函数,该函数用于从ideas表中检索一行:Go pq QueryRow扫描失败,内存地址无效或无指针取消引用,go,pq,Go,Pq,我有以下函数,该函数用于从ideas表中检索一行: func (s *IdeaService) GetIdea(id int64) (*ideaservice.Idea, error) { stmt, err := s.DB.Prepare("SELECT id, name, description, created_on, last_updated FROM ideas WHERE id = $1") if err != nil { return nil, er
func (s *IdeaService) GetIdea(id int64) (*ideaservice.Idea, error) {
stmt, err := s.DB.Prepare("SELECT id, name, description, created_on, last_updated FROM ideas WHERE id = $1")
if err != nil {
return nil, err
}
defer stmt.Close()
var idea *ideaservice.Idea
err = stmt.QueryRow(id).Scan(&idea.ID, &idea.Name, &idea.Description, &idea.CreatedOn, &idea.LastUpdated)
return idea, err
}
在测试中运行此选项时,会出现以下错误:
--- FAIL: TestGetIdea (0.00s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x65be98]
我似乎想不出这个问题。我相信我已经将idea var正确地实例化为指针,然后在Scan方法中为其赋值。有人有什么建议吗?func(s*IdeaService)GetIdea(id int64)(*IdeaService.Idea,错误){
stmt,err:=s.DB.Prepare(“选择id、名称、描述、创建时间、上次更新自ideas,其中id=$1”)
如果错误!=零{
返回零,错误
}
延迟stmt.Close()
var idea*ideaservice.idea
err=stmt.QueryRow(id).Scan(&idea.id、&idea.Name、&idea.Description、&idea.CreatedOn、&idea.LastUpdated)
回主意,呃
}
你能用替换$1
吗?
看看它是否有效?在stmt.QueryRow
中,您正在传递id
。像这样:
stmt,err:=s.DB.Prepare(“选择id、名称、描述、创建时间、上次更新自ideas的id=?”)
如果不起作用,则添加此块:
开关{
case err==sql.ErrNoRows:
log.Fatalf(“没有id为%d的用户”,id为)
案例错误!=零:
log.Fatal(错误)
违约:
log.Println(“ok!”)
}
更新:没有看到关于该问题的评论。是的,他也是对的。一定要把它们修好
并检查
err
被捕获的位置(在这种情况下)。var idea*ideaservice.idea
这不会初始化指针,因此idea
变量为nil
。使用var idea=new(ideaservice.idea)
或idea:=&ideaservice.idea{}
正确初始化变量。使用var v T
声明变量时,变量v
初始化为T
类型的零值,如果类型T
是指针类型,其零值为nil
,则v
也将为nil
。作为比较,执行var idea ideaservice.idea
(假设idea
是一个结构)是完全正确的,因为结构类型的零值是一个结构的值,它的所有字段都初始化为零值。另一种解决方案是将var声明为:var idea ideaservice.idea
,然后从func返回对var的引用吗?从代码角度看,它似乎工作得很好,但我很好奇这是否等同于您的建议是的,我刚刚在前面的评论中添加了这一点。您仍然可以使用return&idea,err
返回指针。您可能应该使用ErrNoRows
检查错误,如果匹配,则返回nil。