我仍然在努力学习Golang的基础知识。
请考虑以下示例代码:
func OpenOutputFile(name string) (fp *os.File) {
fp, err := os.Create(name)
if err != nil {
panic(err)
}
defer func() {
if err := fp.Close(); err != nil {
panic(err)
}
}()
return fp
}
我会假设打电话:
fp := OpenOutputFile("output.txt")
现在会使fp
成为文件指针(*os.File
),这样我就可以调用如下语句:
io.WriteString(fp, "Hello World")
在另一个功能中。但是在调用此方法时,会生成错误:
0 write output.txt: bad file descriptor
因此看来返回的指针无效。如何返回正确形成的指针以与io.WriteString
一起使用?
我很感激帮助!
值得注意的是:当在同一方法中创建文件指针和写入文件指针时,一切都按预期执行。将逻辑分解为函数会导致它无法按预期运行。
答案 0 :(得分:4)
The Go Programming Language Specification
“defer”语句调用其执行被延迟到的函数 周围函数返回的那一刻,要么是因为 周围函数执行了一个return语句,到了结尾 它的功能体,或者因为相应的goroutine 恐慌。
每次执行“延迟”语句时,函数值和 呼叫的参数照常评估并重新保存,但是 不调用实际函数。相反,延迟函数是 在周围函数返回之前立即调用 相反的顺序他们被推迟了。如果是延迟函数值 求值为nil,在调用函数时执行恐慌,而不是 执行“延迟”语句时。
例如,如果延迟函数是函数文字和 周围函数已命名范围内的结果参数 在文字内,延迟函数可以访问和修改 返回之前的结果参数。如果是延期功能 有任何返回值,它们在函数完成时被丢弃。
func OpenOutputFile(name string) (fp *os.File) {
fp, err := os.Create(name)
if err != nil {
panic(err)
}
defer func() {
if err := fp.Close(); err != nil {
panic(err)
}
}()
return fp
}
您打开文件
fp, err := os.Create(name)
您关闭文件
err := fp.Close()
在Close
之后,fp
不再指向有效的文件描述符。