深入defer
defer
语句将函数标记为在当前函数的最后执行。
延迟调用就是在普通函数的前面加上defer
关键字。
包含defer
语句的函数一旦要返回时,被defer
标记的延迟函数就会被调用。延迟函数真正被调用的时机是,当包围函数:
执行返回语句
正常执行到最后
发生了恐慌
例子:
如果一个函数中有多个延迟语句,它们将形成一个栈。最后一个defer
是在闭包函数返回之后第一个执行的,随后依次调用先前的defer
(下方例子会因panic而返回):
延迟函数的参数的值,是它们在被解析求值时的值(而不是最后返回时的值)。
如果一个函数有具名返回值,在该函数中的匿名defer
调用可以在其返回之前修改函数的返回值。
译者注
若要defer内部修改外部函数的返回值,则需要defer语句是匿名函数,外部函数的return值为具名返回值。
之所以要求是匿名defer
函数,是因为Golang不支持具名嵌套函数,则只有匿名嵌套函数才可以构成闭包。有了闭包之后,才可以在闭包内部访问外部函数的变量。
之所以要求外部函数是具名返回值才可以修改,是因为Golang的函数在return
时,若return
变量是匿名的,则该变量值的内存地址是另外申请的,defer
语句在解析求值时并不知道该内存地址,而具名返回值的内存地址在函数解析之初就确定了,所以解析到defer
时,可以知道该地址的值。
最后更新于