当尝试将日志设置代码移动到单独的函数中时,我无法从main函数中隐藏目标文件对象。在以下INCORRECT简化示例中,尝试通过单个函数调用将日志写入 Stderr 和文件:


package main


import (

    "io"

    "log"

    "os"

)


func SetupLogging() {

    logFile, err := os.OpenFile("test.log", os.O_APPEND|os.O_CREATE, 0666)

    if err != nil {

        log.Panicln(err)

    }

    defer logFile.Close()


    log.SetOutput(io.MultiWriter(os.Stderr, logFile))

}


func main() {

    SetupLogging()

    log.Println("Test message")

}

显然是行不通的,因为defer在SetupLogging函数结束时关闭了日志文件。


下面的一个工作示例添加了额外的代码,恕我直言,如果在更大的应用程序中作为模式重复,则会失去一些清晰度:


package main


import (

    "io"

    "log"

    "os"

)


func SetupLogging() *os.File {

    logFile, err := os.OpenFile("test.log", os.O_APPEND|os.O_CREATE, 0666)

    if err != nil {

        log.Panicln(err)

    }


    log.SetOutput(io.MultiWriter(os.Stderr, logFile))

    return logFile

}


func main() {

    logf := SetupLogging()

    defer logf.Close()


    log.Println("Test message")

}

有没有一种不同的方法可以将打开的文件管理完全封装到一个函数中,但仍然可以很好地释放句柄?