当前位置: 首页 > 面试题库 >

在Go中使用defer

乜安志
2023-03-14
问题内容

deferGo 的用途是什么?语言文档说它在周围的函数返回时执行。为什么不将代码放在给定函数的末尾?


问题答案:

我们通常defer用来关闭或释放资源。

周围的函数会在返回之前执行所有延迟的函数调用,即使它会慌乱。如果仅将函数调用放在周围函数的末尾,则在发生紧急情况时将跳过该调用。

而且,延迟函数调用可以通过调用recover内置函数来处理紧急情况。这不能通过函数结尾处的普通函数调用来完成。

每个延迟的调用都放在堆栈中,并在周围函数结束时以相反的顺序执行。颠倒顺序有助于正确分配资源。

defer必须调用该语句才能调用函数。

您可以将其视为实现try-catch-finally块的另一种方法。

结束像try-finally

func main() {
    f, err := os.Create("file")
    if err != nil {
        panic("cannot create file")
    }
    defer f.Close()
    // no matter what happens here file will be closed
    // for sake of simplicity I skip checking close result
    fmt.Fprintf(f,"hello")
}

结束和恐慌处理,例如 try-catch-finally

func main() {
    defer func() {
        msg := recover()
        fmt.Println(msg)
    }()
    f, err := os.Create(".") // . is a current directory
    if err != nil {
        panic("cannot create file")
    }
    defer f.Close()
    // no matter what happens here file will be closed
    // for sake of simplicity I skip checking close result
    fmt.Fprintf(f,"hello")
}

与try-catch-finally相比,好处是没有块和变量作用域的嵌套。这简化了周围功能的结构。

就像finally块一样,如果延迟函数调用可以到达返回的数据,则它们也可以修改返回值。

func yes() (text string) {
    defer func() {
       text = "no"
    }()
    return "yes"
}

func main() {
    fmt.Println(yes())
}


 类似资料:
  • 问题内容: 我正在尝试在Go项目中使用专有的DLL。 DLL的方法描述之一如下所示: 在我的测试Go项目中,我正在执行以下操作: 库被调用,出现错误消息“路径不存在”,但是我认为我的路径类型不正确。这就是为什么库看不到该文件夹​​的原因。 也许有更好的方法可以做到这一点?也许这是Go使用情况的坏案例,我应该找到一些软件包甚至语言? 问题答案: 您的路径可能需要NUL终止:

  • 问题内容: 在新的Go语言中,如何调用C 代码?换句话说,如何包装我的C 类并在Go中使用它们? 问题答案: 更新: 我已经成功地将一个小型测试C ++类与Go链接在一起 如果您使用C接口包装C ++代码,则应该可以使用cgo调用您的库(请参阅中的gmp示例)。 我不确定C ++中的类概念是否真的可以在Go中表达,因为它没有继承。 这是一个例子: 我有一个C ++类定义为: 我想在Go中使用。我将

  • 问题内容: 我试图了解互斥的工作原理。到目前为止,据我了解,它可以进行原子操作并同步对某些数据的访问。 我在这里构建了一个队列数据结构的示例:https : //github.com/arnauddri/algorithms/blob/master/data- structures%2Fqueue%2Fqueue.go 这是一些代码: 但是,当我尝试创建队列并将项目推送到该队列时,出现运行时错误:

  • linux Debian Buster go版本go1.11.6 linux/amd64 gcc版本8.3.0(Debian 8.3.0-6) libmylib.go mylib.h 主.cpp CGO _ ENABLED = 1 go build-o libmylib . so-build mode = c-shared libmylib . go g -L/路径/到/库/ -利米利布 main

  • 问题内容: 我正在使用Vector类型存储字节数组(可变大小) 一切正常,但是当我尝试检索值时,编译器告诉我我需要使用类型断言。所以我添加了这些,然后尝试 但是当我运行它时,它会失败: 是否知道如何从Vector用于存储其数据的空Element接口中“投射” /转换为实际的[] byte数组,然后供以后使用? 更新(Go1): 矢量软件包已于2011-10-18删除。 问题答案: 这对我来说很好。

  • 问题内容: 假设您在拥有一个存储库,然后将其分叉到。您想使用fork而不是主仓库,因此您需要 现在,此存储库中的所有导入路径都将“断开”,这意味着,如果存储库中有多个通过绝对URL相互引用的包,则它们将引用源而不是派生。 有更好的方法手动将其克隆到正确的路径吗? 问题答案: 处理拉取请求 将存储库派生到 下载原始代码: 在那里: 启用上传到您的fork: 将您的更改上传到您的仓库: http://