侧边栏壁纸
博主头像
SeaDream乄造梦

Dream,Don't stop a day of hard and don't give up a little hope。 ——不停止一日努力&&不放弃一点希望。

  • 累计撰写 63 篇文章
  • 累计创建 21 个标签
  • 累计收到 14 条评论

目 录CONTENT

文章目录

go关键字 defer

SeaDream乄造梦
2024-12-09 / 0 评论 / 0 点赞 / 45 阅读 / 1,128 字
温馨提示:
亲爱的,如果觉得博主很有趣就留下你的足迹,并收藏下链接在走叭
  • 数据结构相当于栈,多个defer 倒序执行
  • defer语句用于延迟函数的调用,每次defer都会把一个函数压入栈中,函数返回前再把延迟的函数取出并执行defer 语句会在函数 return 后执行,但是它会先保存该语句的参数值,并在函数退出时按 后进先出(LIFO) 的顺序执行。
  • defer的执行顺序在return之后,但是在返回值返回给调用方之前,所以使用defer可以达到修改返回值的目的。

看四个题

package go_basic

import (
	"fmt"
	"testing"
)

func TestDeferReturn2(t *testing.T) {
	ret := testReturn2()
	fmt.Println("test return:", ret)
}

// 返回值改为命名返回值
func testReturn2() (i int) {
	//var i int

	defer func() {
		i++
		fmt.Println("test defer, i = ", i)
	}()

	return i
}

/*
test defer, i =  1
test return: 1
*/

func TestDeferReturn1(t *testing.T) {
	ret := testReturn1()
	fmt.Println("test return:", ret)
}

func testReturn1() int {
	var i int

	defer func() {
		i++ //defer里面对i增1
		fmt.Println("test defer, i = ", i)
	}()
	fmt.Println(i)
	i = i + 2

	return i
}

/*
0
test defer, i =  3
test return: 2
*/

func TestDeferFuncParameter(t *testing.T) {
	deferFuncParameter()
}
func deferFuncParameter() {
	var aInt = 1

	defer fmt.Println(aInt)

	aInt = 2
	aInt = aInt * 3
	return
}

/*
1
*/

func TestDefer(t *testing.T) {
	testErr()
}

func testErr() {
	var aInt = 1

	defer func() {
		fmt.Println(aInt)
	}()

	aInt++
	aInt = aInt * 3

	return
}
/*
6
 */


总结

  • defer定义的延迟函数参数在defer语句出时就已经确定下来了
  • defer定义顺序与实际执行顺序相反
  • return不是原子操作,执行过程是: 保存返回值(若有)—>执行defer(若有)—>执行ret跳转
  • 申请资源后立即使用defer关闭资源是好习惯
0

评论区