变量在 defer 中的值, 其实在问变量的作用域

有没有想过, 面试中经常问的 变量在 defer 之后的值, 其实是在问 函数变量的作用域

return

从细节来了, 还需要注意

panic

真题测试

以下这是 go语言爱好者 97 期的一道题目。 要求很简单, 代码执行 i, j 的值分别是什么。

这道题虽然代码少, 但是考点还是蛮多的

  1. 核心: 函数变量作用域
  2. defer 执行时间
  3. 闭包
  4. 指针

知识点

这里面所有的内容都可以在 Effective Go 中解决

贪婪算法

什么是贪婪算法, 就是找到局部最优解, 合并后就是全局最优解

怎么找局部最优解, 就是要 对事情进行抽象,掌握事情的本质

defer 延迟执行

FILOreturn
openclose
defer

因此 defer 有什么好考的, 而且实际场景代码也不会那样写(违反了可读性的这一基本之准则)。

所以通常面试中有 defer 的问题都不是在考 defer , 只不过是披上了 defer 的狼皮。

函数及返回值

其实 go 中关于函数返回花样还是挺多的。

func NamedResult(i, j int) (x int)return

感觉和 golang 本身的代码可读性的的理念有一点冲突。 就像为什么不支持三元运算符一样。 其实这样本身也没有什么, 就是一两个 死记硬背 的知识点而已。

defer闭包指针

如果对 函数变量的作用域 理解不清楚的话, 就容易掉坑。

我们开启汇编, 查看一下函数过程

name-unnamed-result.png

从汇编结果可以看到:

UnnamedResult~r2NamedResultxRET
(SP)MOVQ AX, "".~r2+24(SP)

既然如此, 我们就将所有函数的写法全部统一, 不再区分 命名的、 匿名的默认的, 指定的

  1. 命名返回值
  2. return 指定结果

这样看起来, 整个函数就清晰的多了。

实战练习一下

根据之前所说, 我们这里来对函数做一下整形手术。

这样看, defer 是不是很简单了啊?