来源一个题目:
以下golang代码 会输出什么结果:
// Person 定义一个结构体,表示人
type Person struct {age int
}func RunDeferWithPerson() {person := &Person{28}defer fmt.Println("defer1:", person, person.age)defer func(p *Person) { fmt.Println("defer2:", p.age) }(person)defer func() { fmt.Println("defer3:", person.age) }()// 修改person指向的结构体的age值为29person.age = 29// person 重新赋值 新的对象是30person = &Person{30}
}
三个defer 都输出什么??
分析要点
golang的defer 会把调用函数的【参数】 提前保存下来,如果是指针 的没问题; 如果是某个基础类型,会进行一次复制到defer上下文中;
核心在 defer 直接调用函数 的参数 上, 至于 函数内部 则不会保存上下文,而是使用内存逃逸的变量;
结果
输出:
defer3: 30
defer2: 29
defer1: &{29} 28
结论:
修改示例 只有30 才是符合 咱们 直觉的 . 其他2个defer 用法 都得小心咯..
所以 还是 不带参数的 defer func(){ xxxxx }() 比较安全一些.