为了账号安全,请及时绑定邮箱和手机立即绑定

从另一个包调用资源时出现运行时崩溃

从另一个包调用资源时出现运行时崩溃

Go
拉丁的传说 2022-09-12 20:19:16
我正在尝试使用光纤+ zap + pgx创建一个简单的API服务器,我遇到了一个我无法解决的错误。PS C:\Users\risharan\Documents\GitHub\freya> go run .\src\freya.gopanic: runtime error: invalid memory address or nil pointer dereference[signal 0xc0000005 code=0x0 addr=0x0 pc=0xcdca67]goroutine 1 [running]:go.uber.org/zap.(*Logger).check(0x0, 0xc000060500, 0xff0b96, 0x15, 0x0)        C:/Users/risharan/go/pkg/mod/go.uber.org/zap@v1.18.1/logger.go:268 +0x987go.uber.org/zap.(*Logger).Info(0x0, 0xff0b96, 0x15, 0x0, 0x0, 0x0)        C:/Users/risharan/go/pkg/mod/go.uber.org/zap@v1.18.1/logger.go:191 +0x4bfreya/src/db.Init()        C:/Users/risharan/Documents/GitHub/freya/src/db/db.go:19 +0x6dbmain.init.0()        C:/Users/risharan/Documents/GitHub/freya/src/freya.go:15 +0x31exit status 2到目前为止的代码是;包主func init() {    logger.Init()    env.Init()    db.Init()}func main() {    app := fiber.New()    app.Get("/", func(c *fiber.Ctx) error {        return c.SendString("Hello, World!")    })    log.Fatal(app.Listen(":3000"))}包记录器var Say *zap.Loggerfunc Init() {    Say, _ := zap.NewProduction()    defer Say.Sync()}包数据库var Conn *pgxpool.Poolfunc Init() {    c, err := pgxpool.Connect(context.Background(), env.Conf["DATABASE_URL"])    if err != nil {        logger.Say.Fatal("Can't connect to DB", zap.String("Details", err.Error()))    } else {        logger.Say.Info("Connected to Database")    }    Conn = c    defer Conn.Close()    var greeting string    err = Conn.QueryRow(context.Background(), "select 'Hello, this is db!'").Scan(&greeting)    if err != nil {        logger.Say.Error("DB Query failed", zap.String("Details", err.Error()))    }    logger.Say.Info("Connected to DB. DB says; ", zap.String("Details", greeting))}错误消息指示的行        C:/Users/risharan/Documents/GitHub/freya/src/db/db.go:19 +0x6dbmain.init.0()        C:/Users/risharan/Documents/GitHub/freya/src/freya.go:15 +0x31到目前为止,go的错误消息很难解码,我不确定我在这里做错了什么,或者我应该做些什么来修复我的代码。注意:我被告知要进行依赖注入架构。我个人觉得这种模式相当复杂,而且由于我还在学习围棋,我宁愿现在尽可能保持简单。因此,希望答案不要建议我切换模式,除非不可能修复当前基于全局变量的模式。
查看完整描述

1 回答

?
POPMUISE

TA贡献1765条经验 获得超5个赞

您的各种功能中至少有两个问题。Init()

  1. 您正在使用在函数作用域内声明变量的函数,并且不修改在作用域外声明的变量。:=

  2. 您正在使用内部,这是在返回时将执行延迟函数的地方。从本质上讲,这意味着您创建然后销毁资源,使其对任何后续代码都无用。deferInit()Init()Init


如果要赋值给在外部作用域中声明的变量,请不要使用 ,而是使用 。如果您打算在初始化函数外部使用,请不要在初始化函数内执行某些操作。:==defer conn.Close()conn

var Say *zap.Logger


func Init() {

    Say, _ = zap.NewProduction()

}

var Conn *pgxpool.Pool


func Init() {

    c, err := pgxpool.Connect(context.Background(), env.Conf["DATABASE_URL"])

    if err != nil {

        logger.Say.Fatal("Can't connect to DB", zap.String("Details", err.Error()))

    } else {

        logger.Say.Info("Connected to Database")

    }

    Conn = c


    var greeting string

    err = Conn.QueryRow(context.Background(), "select 'Hello, this is db!'").Scan(&greeting)

    if err != nil {

        logger.Say.Error("DB Query failed", zap.String("Details", err.Error()))

    }

    logger.Say.Info("Connected to DB. DB says; ", zap.String("Details", greeting))

}

func init() {

    logger.Init()

    env.Init()

    db.Init()

}


func main() {

    defer func() {

        db.Conn.Close()

        logger.Say.Sync()

    }()


    app := fiber.New()


    app.Get("/", func(c *fiber.Ctx) error {

        return c.SendString("Hello, World!")

    })


    log.Fatal(app.Listen(":3000"))

}


查看完整回答
反对 回复 2022-09-12
  • 1 回答
  • 0 关注
  • 98 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号