英文:
Error assigning gorm.DB to a model variable
问题
我需要帮助解决Golang中指针的问题panic: runtime error: invalid memory address or nil pointer dereference
,我试图将gorm的*gorm.DB
实例返回给另一个文件夹中的模型。
我的想法是在我的模型中实例化一个具有连接的变量,但是当我在func Init()
中实例化时,出现了错误。
main.go
package main
import (
"log"
"github.com/joho/godotenv"
"gitlab.com/project/database"
"gitlab.com/project/models"
)
func main() {
err := godotenv.Load()
if err != nil {
panic("Error loading .env file")
}
database.InitDatabase()
memes, err := models.GetAll();
if err != nil {
log.Fatal("err database get memes")
}
for _, meme := range memes {
log.Printf(meme.Url)
}
}
database/database.go
package database
import (
"gorm.io/gorm"
"gorm.io/driver/postgres"
)
var (
DB *gorm.DB
)
func InitDatabase(){
d, err := gorm.Open(postgres.Open(os.Getenv("DATABASE_URL")), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
DB = d
}
func GetDB() (*gorm.DB) {
return DB
}
models/meme.go
package models
import (
"gorm.io/gorm"
"gitlab.com/webeoparty/api/database"
)
type Meme struct {
gorm.Model
Id uint32
Source string
Filename_local string
Original_filename string
Public_id string
Url string
Secure_url string
Resource_type string
Width uint32
Height uint32
}
var Conn *gorm.DB
func init() {
Conn = database.GetDB()
}
func GetAll() ([]Meme, error) {
var memes []Meme
tx := Conn.Find(&memes)
if tx.Error != nil {
return []Meme{}, tx.Error
}
return memes, nil
}
当我尝试获取*gorm.DB
实例时,出现错误panic: runtime error: invalid memory address or nil pointer dereference。
但是,当我将方法database.GetDB()
写在GetAll()
函数内部时,项目可以正常运行。
package models
...
var Conn *gorm.DB
func GetAll() ([]Meme, error) {
var memes []Meme
Conn = database.GetDB()
tx := Conn.Find(&memes)
if tx.Error != nil {
return []Meme{}, tx.Error
}
return memes, nil
}
英文:
I Need help with pointers in Golang panic: runtime error: invalid memory address or nil pointer dereference
, I'm trying to return an instance of gorm *gorm.DB
to my model in another folder
My idea is to have one variable with the connection in my model instantiated once but when I instanced in func Init()
I have an error
main.go
package main
import (
"log"
"github.com/joho/godotenv"
"gitlab.com/project/database"
"gitlab.com/project/models"
)
func main() {
err := godotenv.Load()
if err != nil {
panic("Error loading .env file")
}
database.InitDatabase()
memes, err := models.GetAll();
if err != nil {
log.Fatal("err database get memes")
}
for _, meme := range memes {
log.Printf(meme.Url)
}
}
database / database.go
package database
import (
"gorm.io/gorm"
"gorm.io/driver/postgres"
)
var (
DB * gorm.DB
)
func InitDatabase(){
d, err := gorm.Open(postgres.Open(os.Getenv("DATABASE_URL")), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
DB = d
}
func GetDB() (*gorm.DB) {
return DB
}
models / meme.go
package models
import (
"gorm.io/gorm"
"gitlab.com/webeoparty/api/database"
)
type Meme struct {
gorm.Model
Id uint32
Source string
Filename_local string
Original_filename string
Public_id string
Url string
Secure_url string
Resource_type string
Width uint32
Height uint32
}
var Conn *gorm.DB
func init() {
Conn = database.GetDB()
}
func GetAll() ([]Meme, error) {
var memes []Meme
tx := Conn.Find(&memes)
if tx.Error != nil {
return []Meme{}, tx.Error
}
return memes, nil
}
the error is panic: runtime error: invalid memory address or nil pointer dereference when i try to get the instance of *gorm.DB
is
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x28 pc=0xf02a78]
goroutine 1 [running]:
gorm.io/gorm.(*DB).getInstance(0x280bb540108?)
C:/Users/edoco/Documents/go-workspace/pkg/mod/gorm.io/gorm@v1.23.5/gorm.go:363 +0x18
gorm.io/gorm.(*DB).Find(0x12d96c8?, {0x1194c40?, 0xc000005998}, {0x0, 0x0, 0x0})
C:/Users/edoco/Documents/go-workspace/pkg/mod/gorm.io/gorm@v1.23.5/finisher_api.go:163 +0x45
gitlab.com/webeoparty/api/models.GetAll()
C:/Users/edoco/Documents/go-workspace/src/webeoparty-api/models/meme.go:34 +0x54
main.main()
C:/Users/edoco/Documents/go-workspace/src/webeoparty-api/main.go:22 +0x4a
exit status 2
but When I write the method database.GetDB()
inside of the func GetAll()
the project run perfectly
package models
...
var Conn *gorm.DB
func GetAll() ([]Meme, error) {
var memes []Meme
Conn = database.GetDB()
tx := Conn.Find(&memes)
if tx.Error != nil {
return []Meme{}, tx.Error
}
return memes, nil
}
答案1
得分: 1
models/meme.go
中的init()
函数在database/database.go
中的DB
被赋值之前被调用(InitDatabase()
尚未被调用)。
这是因为init()
是一个特殊的函数,在导入包时被调用,在变量初始化之后;请参阅Effective Go - The Init Function以获取解释。
您可以通过完全删除全局变量Conn
和models/meme.go
中的init()
函数,并在每个模型函数中调用GetDB()
来解决此问题。
英文:
init()
in models/meme.go
gets called before DB
is assigned in database/database.go
(InitDatabase()
was not called yet).
This is because init()
is special function and gets called when package is imported, after variable initializers; see Effective Go - The Init Function for explanation.
You can solve this problem by completely removing global variable Conn
and init()
function from models/meme.go
and call GetDB()
in each model function to obtain connection.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论