MST
星途 面试题库

面试题:Go语言defer语句与闭包及资源管理的深度应用

在一个需要频繁操作文件的Go项目中,为了确保文件资源的正确关闭,使用defer语句结合闭包来实现文件操作的封装。要求封装后的函数能处理并发操作文件的情况,并且在文件操作完成后,能准确地记录文件操作的时间和结果到日志中。请写出实现该功能的代码,并阐述代码中defer语句与闭包是如何协同工作来保证资源安全和操作记录准确性的。
29.2万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
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语句与闭包协同工作原理

  1. defer语句确保文件关闭:在FileOperation函数中,defer语句在函数结束时(无论是正常结束还是因为错误提前结束)执行文件关闭操作。这样即使operation函数内部发生错误,文件也能被正确关闭,避免资源泄漏。
  2. 闭包传递文件操作逻辑FileOperation函数接受一个闭包作为参数,这个闭包包含了具体的文件操作逻辑。通过这种方式,FileOperation函数可以处理各种不同类型的文件操作,同时保持文件打开、关闭以及操作记录的一致性。
  3. 操作记录准确性:在闭包执行前后记录时间,并在闭包执行完成后根据是否有错误来记录操作结果。由于defer语句保证文件关闭的一致性,并且闭包能确保操作逻辑与时间、结果记录的关联性,所以能准确记录文件操作的时间和结果到日志中。在并发操作时,每个FileOperation调用都有自己独立的文件句柄、时间记录和操作结果,互不干扰,从而保证并发情况下资源安全和操作记录准确性。