亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

無法識別同步中的錯誤。一旦使用

無法識別同步中的錯誤。一旦使用

Go
小唯快跑啊 2022-12-05 11:11:45
我正在做一個關于 Golang 的在線課程。以下代碼片段作為濫用 的示例出現在課程材料中sync.Once:var (    once sync.Once    db   *sql.DB)func DbOnce() (*sql.DB, error) {    var err error    once.Do(func() {        fmt.Println("Am called")        db, err = sql.Open("mysql", "root:test@tcp(127.0.0.1:3306)/test")        if err != nil {            return        }        err = db.Ping()    })    if err != nil {        return nil, err    }    return db, nil}據推測,以上是 SQL 連接管理器的錯誤實現。我們,學生,要自己找出錯誤,我正在努力解決這個問題。代碼即使并行運行也能正常運行。這就是我使用它的方式:func main() {    wg := sync.WaitGroup{}    wg.Add(10)    for i := 0; i < 10; i++ {        go (func() {            db, err := DbOnce()            if err != nil {                panic(err)            }            var v int            r := db.QueryRow("SELECT 1")            err = r.Scan(&v)            fmt.Println(v, err)            wg.Done()        })()    }    wg.Wait()}我知道這里不鼓勵家庭作業問題,所以我不要求一個完整的解決方案,只是一個提示就可以了。錯誤是否與并發有關(即我需要在特定的并發上下文中運行它)?是 sql.Open 的具體用法嗎?
查看完整描述

1 回答

?
藍山帝景

TA貢獻1843條經驗 獲得超7個贊

db變量的初始化是可以的。問題在于返回的錯誤。


如果您DbOnce()是第一次調用并且打開數據庫連接失敗,則會正確返回該錯誤。但是后續調用呢?db初始化代碼不會再次運行,因此可能nil db會返回,并且由于未運行初始化代碼,因此會返回err變量的默認值,即nil. 綜上所述,初始化錯誤丟失,不再報錯。


一種解決方案是在連接失敗時停止應用程序(在第一次調用時)。另一種選擇是將初始化錯誤與 一起存儲在包級變量中db,并從中返回DbOnce()(而不是為此使用局部變量)。前者的優點是您不必處理從DbOnce()返回的錯誤,因為它甚至不必返回錯誤(如果出現錯誤,您的應用程序將終止)。


后者可能看起來像這樣:


var (

    once  sync.Once

    db    *sql.DB

    dbErr error

)


func DbOnce() (*sql.DB, error) {

    once.Do(func() {

        fmt.Println("Am called")

        db, dbErr = sql.Open("mysql", "root:test@tcp(127.0.0.1:3306)/test")

        if dbErr != nil {

            return

        }

        dbErr = db.Ping()

    })

    return db, dbErr

}


查看完整回答
反對 回復 2022-12-05
  • 1 回答
  • 0 關注
  • 92 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號