typora/note/Go/for循环中尽量不要使用defer.md

51 lines
1.0 KiB
Markdown
Raw Permalink Normal View History

2024-12-11 21:48:55 -05:00
### for 循环中禁止使用defer
- 直接在 for 循环中使用 defer 很可能使得 defer 不能执行,导致内存泄露或者其他资源问题,所以应该将 defer 放到外层。
- 若确实需要使用 defer可以将逻辑封装为一个独立函数或者使用闭包
- 错误
```go
func readFiles(files []string) {
for i:=0;i<len(files);i++{
f,err:=os.Open(files[i])
if err!=nil{
println(err.Error())
continue
}
// bug here
// 在循环中的 defer 只有在循环结束后才会执行
// 若 files 很多,会导致大量文件句柄未及时释放
defer f.Close()
bf,err:=io.ReadAll(f)
if err!=nil{
println(err.Error())
}else{
println(string(bf))
}
}
}
```
- 正确
```go
func readFiles(files []string) {
for i:=0;i<len(files);i++{
readFile(files[i])
}
}
func readFile(name string){
f,err:=os.Open(name)
if err!=nil{
println(err.Error())
return
}
defer f.Close()
bf,err:=io.ReadAll(f)
if err!=nil{
println(err.Error())
}else{
println(string(bf))
}
}
```