golang defer return 特性 实例

package main

import "fmt"

func calc(index string, a, b int) int {
    ret := a + b
    fmt.Println(index, a, b, ret)
    return ret
}

func main() {
    a := 1
    b := 2
    defer calc("1", a, calc("10", a, b))

    a = 0
    defer calc("2", a, calc("20", a, b))

    b = 1
}

defer在定义的时候会计算好调用函数的参数,所以会优先输出10、20这两个参数,之后就是根据定义的顺序倒序执行。

package main

import (
    "fmt"
)

func main() {
    fmt.Println(a())    // 1 0 1
    fmt.Println(c())    // 2
    fmt.Println(f0())   // 6
    fmt.Println(f1())   // 1
    fmt.Println(*f1p()) // 6
    fmt.Println(f2())   // 1
    fmt.Println(f3())   // 6
    fmt.Println(f40())  // 1
    fmt.Println(f4())   // 0
}

/**
 * 当defer被声明时,其参数就会被实时解析
 * defer执行顺序为先进后出
 */
func a() int {
    i := 0
    defer fmt.Println(i) //输出0,因为i此时就是0
    i++
    defer fmt.Println(i) //输出1,因为i此时就是1
    return i
}

/**
 * 当执行return 1时,1先赋值给i.然后defer代码块开始执行,对i进行自增操作。 因此输出2
 */
func c() (i int) {
    defer func() {
        i++
    }()
    return 1
}

func f0() (t int) {
    t = 1
    defer func() {
        t = t + 5
    }()
    return t
}

/**
 * t先赋值给r,然后执行defer,虽然t被改了,由于值传递返回值仍然是1
 */
func f1() (r int) {
    t := 1
    defer func() {
        t = t + 5
    }()
    return t
}

/**
 * t先赋值给r,然后执行defer,t被改了,由于传的是地址,返回值是6
 */
func f1p() (r *int) {
    t := 1
    defer func() {
        t = t + 5
    }()
    return &t
}

/**
 * r默认值是0,作为参数传入了defer不会修改r的值,1会赋值给r,返回值为1
 */
func f2() (r int) {
    defer func(r int) {
        r = r + 5
    }(r)
    return 1
}

/**
 * 1赋值给r,然后执行defer,此时r被修改为6,返回的r值为6
 */
func f3() (r int) {
    defer func() {
        r = r + 5
    }()
    return 1
}

/**
 * 0赋值给result,然后defer执行,result值自增变为1,返回值为1
 */
func f40() (result int) {
    defer func() {
        result++
    }()
    return 0
}

/**
 * return不写返回变量,声明的变量名字也会被返回0
 */
func f4() (result int) {
    result = 0
    return
}

/**
 * 传入地址,i的值最终被改为了15,但是返回值是10
 */
func f5(i *int) int {
    *i = 10
    defer func() {
        *i = 15
    }()
    return *i
}

此处评论已关闭