Go语言之defer
ycyoes · · 1500 次点击 · · 开始浏览defer fmt.Println("The finishing touches.")
这里的表达式语句必须代表一个函数或方法的调用。注意,既然是表达式语句,那么一些调用表达式就是不被允许出现在这里的。比如,针对各种内建函数的那些调用表达式。因为它们不能被称为表达式语句。另外,在这个位置上出现的表达式语句是不能被圆括号括起来的。
defer func() {
fmt.Println("The finishing touches.")
}()
注意,一个针对匿名函数的调用表达式是由一个函数字面量和一个代表了调用操作的一对圆括号组成的。
func begin(funcName string) string {
fmt.Printf("Enter function %s.\n", funcName)
return funcName
}
func end(funcName string) string {
fmt.Printf("Exit function %s.\n", funcName)
return funcName
}
func record() {
defer end(begin("record"))
fmt.Println("In function record.")
}
outputs:
func printNumbers() {
for i := 0; i < 5; i++ {
defer fmt.Printf("%d ", i)
}
}
outputs:
fmt.Printf("%d ", 1)
fmt.Printf("%d ", 2)
fmt.Printf("%d ", 3)
fmt.Printf("%d ", 4)
对延迟函数调用表达式的求值顺序是与它们所在的defer语句被执行的顺序完全相反的。每当Go语言把已代入参数值的延迟函数调用表达式另行存储后,还会把它追加到一个专门为当前外围函数存储延迟函数调用表达式的列表中。而这个列表总是LIFO(Last In First Out,即后进先出)的。因此,这些延迟函数调用表达式的求值顺序会是:
fmt.Printf("%d ", 4)
fmt.Printf("%d ", 3)
fmt.Printf("%d ", 2)
fmt.Printf("%d ", 1)
fmt.Printf("%d ", 0)
例:
func appendNumbers(ints []int) (result []int) {
result = append(ints, 1)
fmt.Println(result)
defer func() {
result = append(result, 2)
}()
result = append(result, 3)
fmt.Println(result) defer func() {
result = append(result, 4)
}()
result = append(result, 5)
fmt.Println(result) defer func() {
result = append(result, 6)
}()
return result
}
outputs:
func printNumbers() {
for i := 0; i < 5; i++ {
defer func() {
fmt.Printf("%d ", i)
}()
}
}
outputs:
fmt.Printf("%d ", i)
defer func() {
fmt.Printf("%d ", i)
}()
defer func() {
fmt.Printf("%d ", i)
}()
defer func(i int) {
fmt.Printf("%d ", i)
}(i)
defer func(i int) {
fmt.Printf("%d ", i)
}(0)
func modify(n int) (number int) {
fmt.Println(number)
defer func() {
number += n
}()
number++
return
}
func modify(n int) (number int) {
fmt.Println(number)
defer func(plus int) (result int) {
result = n + plus
number += result
return
}(3)
number++
return
}
modify(2),结果为:6
有疑问加站长微信联系(非本文作者)
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
关注微信- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码` - 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传
收入到我管理的专栏 新建专栏
defer fmt.Println("The finishing touches.")
这里的表达式语句必须代表一个函数或方法的调用。注意,既然是表达式语句,那么一些调用表达式就是不被允许出现在这里的。比如,针对各种内建函数的那些调用表达式。因为它们不能被称为表达式语句。另外,在这个位置上出现的表达式语句是不能被圆括号括起来的。
defer func() {
fmt.Println("The finishing touches.")
}()
注意,一个针对匿名函数的调用表达式是由一个函数字面量和一个代表了调用操作的一对圆括号组成的。
func begin(funcName string) string {
fmt.Printf("Enter function %s.\n", funcName)
return funcName
}
func end(funcName string) string {
fmt.Printf("Exit function %s.\n", funcName)
return funcName
}
func record() {
defer end(begin("record"))
fmt.Println("In function record.")
}
outputs:
func printNumbers() {
for i := 0; i < 5; i++ {
defer fmt.Printf("%d ", i)
}
}
outputs:
fmt.Printf("%d ", 1)
fmt.Printf("%d ", 2)
fmt.Printf("%d ", 3)
fmt.Printf("%d ", 4)
对延迟函数调用表达式的求值顺序是与它们所在的defer语句被执行的顺序完全相反的。每当Go语言把已代入参数值的延迟函数调用表达式另行存储后,还会把它追加到一个专门为当前外围函数存储延迟函数调用表达式的列表中。而这个列表总是LIFO(Last In First Out,即后进先出)的。因此,这些延迟函数调用表达式的求值顺序会是:
fmt.Printf("%d ", 4)
fmt.Printf("%d ", 3)
fmt.Printf("%d ", 2)
fmt.Printf("%d ", 1)
fmt.Printf("%d ", 0)
例:
func appendNumbers(ints []int) (result []int) {
result = append(ints, 1)
fmt.Println(result)
defer func() {
result = append(result, 2)
}()
result = append(result, 3)
fmt.Println(result) defer func() {
result = append(result, 4)
}()
result = append(result, 5)
fmt.Println(result) defer func() {
result = append(result, 6)
}()
return result
}
outputs:
func printNumbers() {
for i := 0; i < 5; i++ {
defer func() {
fmt.Printf("%d ", i)
}()
}
}
outputs:
fmt.Printf("%d ", i)
defer func() {
fmt.Printf("%d ", i)
}()
defer func() {
fmt.Printf("%d ", i)
}()
defer func(i int) {
fmt.Printf("%d ", i)
}(i)
defer func(i int) {
fmt.Printf("%d ", i)
}(0)
func modify(n int) (number int) {
fmt.Println(number)
defer func() {
number += n
}()
number++
return
}
func modify(n int) (number int) {
fmt.Println(number)
defer func(plus int) (result int) {
result = n + plus
number += result
return
}(3)
number++
return
}
modify(2),结果为:6