英文:
golang runtime error when i am trying to use db.QueryRow
问题
我有一个controller.go
文件:
package controller
import (
"github.com/fishkaoff/todoList/pkg/postgresql"
"github.com/gin-gonic/gin"
"net/http"
"context"
)
type Task struct {
Title string
Description string
}
func GetTasks(c *gin.Context) {
var response *Task
err := db.Conn.QueryRow(context.Background(), "select * from tasks").Scan(&response.Title, &response.Description)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "error"})
}
c.JSON(200, gin.H{
"page": "gettasks",
"tasks": response,
})
}
当我发送请求时,它返回以下错误信息:
runtime error: invalid memory address or nil pointer dereference
C:/Program Files/Go/src/runtime/panic.go:260 (0xb7bab5)
panicmem: panic(memoryError)
C:/Program Files/Go/src/runtime/signal_windows.go:255 (0xb7ba85)
sigpanic: panicmem()
D:/workspace/golangWWW/pkg/mod/github.com/jackc/pgx/v4@v4.17.2/conn.go:551 (0x1015db1)
(*Conn).Query: simpleProtocol := c.config.PreferSimpleProtocol
D:/workspace/golangWWW/pkg/mod/github.com/jackc/pgx/v4@v4.17.2/conn.go:663 (0x101b9dc)
(*Conn).QueryRow: rows, _ := c.Query(ctx, sql, args...)
D:/workspace/golangWWW/todolist/internal/controller/controller.go:17 (0x101b9ab)
GetTasks: err := db.Conn.QueryRow(context.Background(), "select * from tasks").Scan(&response.Title, &response.Description)
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/context.go:173 (0xeb99c1)
(*Context).Next: c.handlers[c.index](c)
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/recovery.go:101 (0xeb99ac)
CustomRecoveryWithWriter.func1: c.Next()
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/context.go:173 (0xeb8ac6)
(*Context).Next: c.handlers[c.index](c)
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/logger.go:240 (0xeb8aa9)
LoggerWithConfig.func1: c.Next()
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/context.go:173 (0xeb7bd0)
(*Context).Next: c.handlers[c.index](c)
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/gin.go:616 (0xeb7838)
(*Engine).handleHTTPRequest: c.Next()
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/gin.go:572 (0xeb74fc)
(*Engine).ServeHTTP: engine.handleHTTPRequest(c)
C:/Program Files/Go/src/net/http/server.go:2947 (0xd70feb)
serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
C:/Program Files/Go/src/net/http/server.go:1991 (0xd6d6c6)
(*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
C:/Program Files/Go/src/runtime/asm_amd64.s:1594 (0xb96320)
goexit: BYTE $0x90 // NOP
db.Conn
是从db.go
导入的:
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) {
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()
}
InitDatabase
在main.go
中调用。
数据库表和列已创建。
我正在使用pgx v4版本。
P.S:对于我的糟糕英语表示抱歉,我不是以英语为母语的人。
英文:
i have controller.go:
package controller
import (
"github.com/fishkaoff/todoList/pkg/postgresql"
"github.com/gin-gonic/gin"
"net/http"
"context"
)
type Task struct {
Title string
Description string
}
func GetTasks(c *gin.Context) {
var response *Task
err := db.Conn.QueryRow(context.Background(), "select * from tasks").Scan(&response.Title,
&response.Description)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error":"error"})
}
c.JSON(200, gin.H{
"page":"gettasks",
"tasks": response,
})
}
when i am sending request it returns me
```runtime error: invalid memory address or nil pointer dereference
C:/Program Files/Go/src/runtime/panic.go:260 (0xb7bab5)
panicmem: panic(memoryError)
C:/Program Files/Go/src/runtime/signal_windows.go:255 (0xb7ba85)
sigpanic: panicmem()
D:/workspace/golangWWW/pkg/mod/github.com/jackc/pgx/v4@v4.17.2/conn.go:551 (0x1015db1)
(*Conn).Query: simpleProtocol := c.config.PreferSimpleProtocol
D:/workspace/golangWWW/pkg/mod/github.com/jackc/pgx/v4@v4.17.2/conn.go:663 (0x101b9dc)
(*Conn).QueryRow: rows, _ := c.Query(ctx, sql, args...)
D:/workspace/golangWWW/todolist/internal/controller/controller.go:17 (0x101b9ab)
GetTasks: err := db.Conn.QueryRow(context.Background(), "select * from tasks").Scan(&response.Title, &response.Description)
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/context.go:173 (0xeb99c1)
(*Context).Next: c.handlers[c.index](c)
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/recovery.go:101 (0xeb99ac)
CustomRecoveryWithWriter.func1: c.Next()
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/context.go:173 (0xeb8ac6)
(*Context).Next: c.handlers[c.index](c)
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/logger.go:240 (0xeb8aa9)
LoggerWithConfig.func1: c.Next()
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/context.go:173 (0xeb7bd0)
(*Context).Next: c.handlers[c.index](c)
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/gin.go:616 (0xeb7838)
(*Engine).handleHTTPRequest: c.Next()
D:/workspace/golangWWW/pkg/mod/github.com/gin-gonic/gin@v1.8.1/gin.go:572 (0xeb74fc)
(*Engine).ServeHTTP: engine.handleHTTPRequest(c)
C:/Program Files/Go/src/net/http/server.go:2947 (0xd70feb)
serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
C:/Program Files/Go/src/net/http/server.go:1991 (0xd6d6c6)
(*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
C:/Program Files/Go/src/runtime/asm_amd64.s:1594 (0xb96320)
goexit: BYTE $0x90 // NOP```
db.Conn is imported from db.go:
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) {
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()
}
InitDatabase is calling in main.go
in database table and columns are created
i am using pgx v4
P.S: sorry for my bad english, i am not a native speaker
_________________________________________________________
答案1
得分: 2
你已经分配了内存来存储 *Task
,而不是 Task
。
然后当你尝试获取 response.Title
和 response.Description
的地址时,这些字段没有地址,因为 response
是一个指针,但没有指向有效的任务。
尝试使用以下代码:
var response Task
现在你实际上已经为 Title
和 Description
字段分配了空间,因此有地方来存储这些值。
英文:
var response *Task
You have allocated memory to store a *Task
, not a Task
.
Then when you
.Scan(&response.Title, &response.Description)
Attempt to take the address of response.Title
and response.Description
. These fields don't have an address because response
is a pointer but doesn't point to a valid task.
Try:
var response Task
Now you actually have allocated space for the Title
and Description
fields and thus have somewhere to store those values.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论