defer 和 return 执行的先后顺序

Go 中 defer 和 return 执行的先后顺序

多个defer的执行顺序为”后进先出”;

defer、return、返回值三者的执行逻辑应该是:return最先执行,return负责将结果写入返回值中;接着defer开始执行一些收尾工作;最后函数携带当前返回值退出。

如果函数的返回值是无名的(不带命名返回值), 则go语言会在执行return的时候会执行一个类似创建一个临时变量作为保存return值的动作, 而有名返回值的函数, 由于返回值在函数定义的时候已经将该变量进行定义, 在执行return的时候会先执行返回值保存操作,

而后续的defer函数会改变这个返回值(虽然defer是在return之后执行的, 但是由于使用的函数定义的变量, 所以执行defer操作后对该变量的修改会影响到return的值

eg1:不带命名返回值的函数

package main
import "fmt"
func main() {
		fmt.Println("return:", test())// defer 和 return之间的顺序是先返回值, i=0,后defer
}
func test() int {//这里返回值没有命名
    var i int
    defer func() {
        i++
        fmt.Println("defer1", i) //作为闭包引用的话,则会在defer函数执行时根据整个上下文确定当前的值。i=2
    }()
    defer func() {
        i++
        fmt.Println("defer2", i) //作为闭包引用的话,则会在defer函数执行时根据整个上下文确定当前的值。i=1
    }()
    return i
}

test() 先返回 i=0

defer2先于defer1执行

输出结果为:

defer2 1

defer1 2

return: 0

eg2:带命名返回值的函数:

package main
import "fmt"
func main() {
    fmt.Println("return:", test())
}
func test() (i int) { //返回值命名i
    defer func() {
        i++
        fmt.Println("defer1", i)
    }()
    defer func() {
        i++
        fmt.Println("defer2", i)
    }()
    return i
}

对外部变量的引用作为函数参数(i), 则在defer申明时就把值传递给defer。

输出结果为:

defer2 1

defer1 2

return: 2

理解return 返回值的运行机制:

为了弄清上述两种情况的区别, 我们首先要理解return 返回值的运行机制: return 并非原子操作, 分为赋值, 和返回值两步操作

eg1 : 实际上return 执行了两步操作, 因为返回值没有命名, 所以return 默认指定了一个返回值(假设为s), 首先将i赋值给s,后续的操作因为是针对i,进行的, 所以不会影响s, 此后因为s不会更新, 所以return s 不会改变

相当于:

var i int

s := i

return s

eg2 : 同上, s 就相当于 命名的变量i, 因为所有的操作都是基于命名变量i(s), 返回值也是i, 所以每一次defer操作, 都会更新返回值i

注意: return 只能用于函数体和协程退出, 包括 main 函数;

实例: defer 是否影响 函数运行效率(return 返回值的效率)

package main
import (
"fmt"
"time"
)
func main() {
		fmt.Println("return:", test())
}
func test() (i int) { //返回值命名i
    defer func() {
    i++
    fmt.Println("defer1", i)
    }()
    defer func() {
    i = 100
    fmt.Println("defer2", i)
    }()
    defer time.Sleep(10 * time.Second) // 影响到了函数执行的效率, 我们看到 return 返回值 是最后返回
    defer func() {
    time.Sleep(10 * time.Second)
    fmt.Println("延迟执行")
    }() // 影响到了函数执行的效率
    return i
}
/*
延迟执行
defer2 100
defer1 101
return: 101
*/

限 时 特 惠: 本站每日持续更新海量各大内部创业教程,一年会员只需98元,全站资源免费下载 点击查看详情
站 长 微 信: lzxmw777

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注