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

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

當資源超出周圍函數的范圍時,如何推遲資源清理?

當資源超出周圍函數的范圍時,如何推遲資源清理?

Go
拉莫斯之舞 2022-09-19 15:03:46
讓我們以這段代碼為例,它使記錄器寫入本地文件而不是標準輸出:f, err := os.OpenFile("filename", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)if err != nil {        log.Fatal(err)}   defer f.Close()log.SetOutput(f)作者將此代碼直接放入函數中,使其按預期工作。但是,如果我想把這個代碼放到一個專用的函數中,然后調用它,那么它將不再起作用,因為在使用記錄器之前會調用它。main()main()f.Close()例如(如果上面的代碼現在位于名為 的函數中):logToFile()main() {   logToFile()   log.Print("I'm going to end up in stdout\n")}這是否可以移動到自己的功能中,并且仍然按預期工作?我在打開/關閉數據庫連接時也遇到過同樣的情況。而且似乎唯一的方法就是在 里面做這兩件事,但我認為如果我們能把它分成函數,代碼看起來會更干凈,更SoC。這是圍棋中的禁忌嗎?main()
查看完整描述

2 回答

?
侃侃無極

TA貢獻2051條經驗 獲得超10個贊

你在尋找這樣的東西嗎?


type closerFunc func() error


func logToFile(path string) closerFunc {

    f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)

    if err != nil {

        log.Fatal(err)

    }   


    log.SetOutput(f)


    return func() error {

        return f.Close()

    }

}

使用方法:


func main() {

    closerFn := logToFile("filename")

    defer closerFn()


    log.Print("logs to file\n")

}


查看完整回答
反對 回復 2022-09-19
?
慕尼黑5688855

TA貢獻1848條經驗 獲得超2個贊

一種選擇是使用延續傳遞樣式,將要在塊內執行的代碼作為顯式參數傳遞:defer


func withLogToFile(filename string, body func()) {

    f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)

    if err != nil {

        log.Fatal(err)

    }

    prevOut := log.Writer()

    log.SetOutput(f)

    defer func() {

        log.SetOutput(prevOut)

        if err := f.Close(); err != nil {

            log.Fatal(err)

        }

    }()


    body()

}

然后呼叫站點變為:


func main() {

    withLogToFile(filename, func() {

        log.Print("I'm going to end up in ", filename)

    })

}

(https://play.golang.org/p/ebCvtzufU5U)


查看完整回答
反對 回復 2022-09-19
  • 2 回答
  • 0 關注
  • 95 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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