面试题答案
一键面试package main
import (
"fmt"
"log"
"os"
"time"
)
// FileOperation 封装文件操作的函数
func FileOperation(filePath string, operation func(file *os.File) error) error {
file, err := os.OpenFile(filePath, os.O_RDWR|os.O_CREATE, 0644)
if err != nil {
return err
}
defer func() {
if err := file.Close(); err != nil {
log.Printf("文件关闭错误: %v", err)
}
}()
start := time.Now()
err = operation(file)
elapsed := time.Since(start)
var result string
if err == nil {
result = "成功"
} else {
result = fmt.Sprintf("失败: %v", err)
}
log.Printf("文件操作时间: %s, 结果: %s", elapsed, result)
return err
}
可以通过以下方式调用这个函数:
func main() {
filePath := "test.txt"
err := FileOperation(filePath, func(file *os.File) error {
// 模拟文件操作,例如写入内容
_, err := file.WriteString("Hello, World!")
return err
})
if err != nil {
log.Printf("执行文件操作时出错: %v", err)
}
}
defer语句与闭包协同工作原理
- defer语句确保文件关闭:在
FileOperation
函数中,defer
语句在函数结束时(无论是正常结束还是因为错误提前结束)执行文件关闭操作。这样即使operation
函数内部发生错误,文件也能被正确关闭,避免资源泄漏。 - 闭包传递文件操作逻辑:
FileOperation
函数接受一个闭包作为参数,这个闭包包含了具体的文件操作逻辑。通过这种方式,FileOperation
函数可以处理各种不同类型的文件操作,同时保持文件打开、关闭以及操作记录的一致性。 - 操作记录准确性:在闭包执行前后记录时间,并在闭包执行完成后根据是否有错误来记录操作结果。由于
defer
语句保证文件关闭的一致性,并且闭包能确保操作逻辑与时间、结果记录的关联性,所以能准确记录文件操作的时间和结果到日志中。在并发操作时,每个FileOperation
调用都有自己独立的文件句柄、时间记录和操作结果,互不干扰,从而保证并发情况下资源安全和操作记录准确性。