我还在努力学习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
呢?
感谢你的帮助!
注意:当文件指针的创建和对文件指针的写入存在于同一个方法中时,一切都按预期执行。将逻辑分解为函数会导致它不按预期运行。
2条答案
按热度按时间66bbxpm51#
The Go Programming Language Specification
延迟语句
一个“defer”语句调用的函数的执行被延迟到周围函数返回的时刻,要么是因为周围的函数执行了一个return语句,到达了函数体的末尾,要么是因为相应的goroutine出现了恐慌。
每次执行“defer”语句时,调用的函数值和参数都会像往常一样求值并重新保存,但实际函数不会被调用。相反,延迟函数会在周围函数返回之前立即被调用,顺序与它们被延迟的顺序相反。如果延迟函数值求值为nil,则在调用函数时执行会出现异常,而不是在执行“defer”语句时。
例如,如果延迟函数是一个函数文本,并且周围的函数具有在文本范围内的命名结果参数,则延迟函数可以在返回结果参数之前访问和修改这些参数。如果延迟函数具有任何返回值,则在函数完成时将丢弃这些值。
你打开文件
你关闭文件
在
Close
之后,fp
不再指向有效的文件描述符。krugob8w2#
返回close函数并在更高的作用域中延迟它对我来说很有效,但我不知道这在Go语言中是否是一个好的实践,它依赖于原始函数之外的关闭/延迟:
然后在更高的范围内:
使用逐步调试器确认-在程序结束时,正确调用延迟关闭函数并关闭文件描述符。