- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
开始之前,先考虑下下面的代码的执行结果:
package main
import "fmt"
func test() int {
i := 0
defer func() {
fmt.Println("defer1")
}()
defer func() {
i += 1
fmt.Println("defer2")
}()
return i
}
func main() {
fmt.Println("return", test())
}
defer 是 Go 编程语言中的一个关键字,用于在函数执行结束后延迟执行指定的函数调用。 defer 的使用非常灵活,它通常用于执行一些清理操作、资源释放、日志记录等任务。以下是对 defer 的详细介绍:
defer 的语法 :
defer
后面跟随一个函数调用,该函数会在包含 defer
语句的函数执行完毕后被调用。 defer someFunction()
执行时机 :
defer
函数调用会在包含 defer
语句的函数返回之前执行,即使在函数中间有 return
语句也是如此。 defer
中的操作在函数结束时始终执行,无论函数是正常返回还是出现异常。 多个 defer 语句 :
defer
语句,它们会以后进先出(LIFO)的顺序执行。 defer
语句会最先执行,而最先出现的 defer
语句会最后执行。 常见用途 :
defer
常用于关闭文件、释放锁、释放内存等资源管理任务,确保资源在函数结束时得到正确释放。 defer
可以用于记录错误日志或执行清理操作,以确保即使发生错误,资源也能得到释放。 defer
还可以用于记录函数的执行情况,以进行性能分析或跟踪代码路径。 示例 : 下面是一个使用 defer 的示例,演示了文件的打开和关闭操作:
func readFile(filename string) error {
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close() // 确保文件在函数返回前关闭
// 文件操作...
return nil
}
注意事项 :
defer
不仅用于函数的返回,还可以用于方法(类似于面向对象编程中的析构函数)。 defer
中的参数会在 defer
语句执行时被求值,因此如果你有多个 defer
语句使用相同的参数,它们会被依次求值。 defer
中的闭包,以避免出现意外的行为。 defer 语句中的函数调用会在包含 defer 语句的函数返回之前执行。无论函数是正常返回还是在执行中发生了 panic, defer 中的函数都会按照后进先出(LIFO)的顺序执行。这确保了在函数结束时进行清理和释放资源,以及在函数执行期间处理错误或日志记录等任务.
以下是关于 defer 执行时机的详细解释:
正常返回时的 defer 执行 :
defer
语句时,不会立即执行 defer
中的函数调用,而是将它们压入一个栈中,以便在函数返回时执行。 defer
函数调用会按照后进先出的顺序执行,确保最后一个 defer
最先执行。 发生 panic 时的 defer 执行 :
defer
中的函数,然后再传播 panic,这允许在 panic 后执行清理操作。 下面是一个示例,说明了 defer 的执行时机:
func exampleFunction() {
defer fmt.Println("Deferred 1")
defer fmt.Println("Deferred 2")
fmt.Println("Function body")
panic("Something went wrong")
}
func main() {
exampleFunction()
}
在这个示例中, exampleFunction 包含两个 defer 语句和一个 panic。当 exampleFunction 调用时,它首先打印 "Function body",然后执行 defer 中的函数。在 panic 发生后, defer 语句中的函数会按照后进先出的顺序执行。所以, main 函数的输出将是:
Function body
Deferred 2
Deferred 1
panic: Something went wrong
正如示例所示, defer 中的函数在函数返回之前或在 panic 发生后都会执行,这使得它在资源管理和错误处理方面非常有用.
现在回到最开始的问题,在上面的代码中, test 函数包含两个 defer 语句,以及一个 return 语句。在 main 函数中,我们调用 test 并输出其返回值。让我们来解释每一步并分析输出的结果:
i
初始化为 0
。 defer
语句中的匿名函数只是打印 "defer1",不对 i
进行任何修改。 defer
语句中的匿名函数增加了 i
的值,然后打印 "defer2"。 现在,让我们分析 test 函数的执行流程:
i
初始化为 0
。 defer
语句注册的函数(打印 "defer1")会在函数返回之前执行,但它没有影响 i
的值。 defer
语句注册的函数(增加 i
的值并打印 "defer2")也会在函数返回之前执行,但在执行时, i
的值仍然为 0
。 return i
语句返回 0
。 因此, test 函数返回 0 ,但在执行过程中,两个 defer 函数都被执行,按照注册的顺序分别打印 "defer1" 和 "defer2".
在 main 函数中,我们调用 test 并输出其返回值,因此最终的输出是:
defer2
defer1
return 0
这是因为 defer2 和 defer1 的输出分别在 test 函数调用结束之前执行,而 return 0 的结果在函数返回后被 main 函数输出.
声明:本作品采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可,使用时请注明出处。 Author: mengbin blog: mengbin Github: mengbin92 cnblogs: 恋水无意 。
最后此篇关于godefer简介的文章就讲到这里了,如果你想了解更多关于godefer简介的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我已经使用 goclipse 有一段时间了。除了在编辑器中打开的同一个文件中的定义之外,我从来没有让 godef 在 eclipse 中工作。我从来没有打扰过,但这次我想我会解决这个问题。但看起来我无
我安装 godef: $ go get -u github.com/rogpeppe/godef 看起来不错: $ which godef /home/username/go/bin/godef 就在
我正在尝试在 OpenSUSE 上使用来自 emacs 的 godef。 尝试安装 godef:去获取 code.google.com/p/rog-go/exp/cmd/godef 也试过:go in
first I pull the soure code or zipfile, They both show the same error log like this when I go build
我正在尝试使用以下命令安装 godef 二进制文件: go get -v code.google.com/p/rog-go/exp/cmd/godef 但是它总是给我错误: package code.
我通过 C GoLang 的包在 GoLang 上编写了一个包含 Objective-C 代码(调用一些 OSX API)的程序,我需要从 Go 传递类型为 T 的变量代码到 Objective-C
在我升级到 Go 1.4 后,godef 不再在标准库中找到很多东西,例如 Testing.Fatalf。 当我尝试 go get -u 时,出现以下错误: package code.google.c
我已经通过安装 godef go get github.com/rogpeppe/godef 我安装了 emacs go-mode,并在我的 .bashrc 中导出了以下内容: export GORO
我正在使用带有Go扩展名的VS Code,但是我注意到当我右键单击某个方法并选择“转到定义”时,找不到任何定义。例如, 这是在我使用Cobra生成的示例应用程序中: cobra init myCobr
我是一名优秀的程序员,十分优秀!