Golang 中国
func a() {
    i := 0
    defer fmt.Println(i)
    i++
    return
}

这里的输出为 0 这个是因为defer语句前 i=0
那下面这段

package main

import (
    "io"
    "log"
)

func func1(s string) (n int, err error) {
    defer func() {
        log.Printf("func1(%q) = %d, %v", s, n, err)
    }()
    return 7, io.EOF
}

func main() {
    func1("Go")
}

结果 Output: 2011/10/04 10:46:11 func1(“Go”) = 7, EOF
如何传递参数的?

望指点

3 回复
elvindu
#1 elvindu • 2018-01-29 10:52

defer 和defer func(){}()有点不一样,第一个会把所有东西都压入堆栈,包括要输出的i,这个时候就要看i是指针类型还是值类型了。但是后一个只是只是把函数压人堆栈,里面要输出的数据没有压入,所以输出不一样。。是有点诡异。。。。是个坑啊

nulijiabei
#2 nulijiabei • 2018-03-03 17:16

defer 是在 return 之后执行的 …

package main

import (
    "io"
    "log"
)

func func1(s string) (n int, err error) {
    defer func() {
        log.Printf("func1(%q) = %d, %v", s, n, err)
    }()
    n = 7
    err = io.EOF
    return
}
func main() {
    func1("Go")
}

http://www.nljb.net
http://github.com/nulijiabei

bigbear
#3 bigbear • 2018-03-06 14:37
  1. defer的作用域的一个函数, 不是代码块.
  2. defer可以理解为把一个子函数压入执行栈的最底部, 函数执行结束时, 自动执行此子函数.
  3. 还是涉及子函数被调用时, 子函数参数的取值问题, defer fmt.Print(“%d”,i) 如果i是值类型的, i的取值, 是在defer语句发生时取的, 而不是在fmt子函数被执行时才确定i的值. 如果i是指针类型的, 就是子函数运行时寻址取值.
    (The arguments to the deferred function (which include the receiver if the function is a method) are evaluated when the defer executes, not when the call executes.)
    defer的函数如果是一个struct的方法, 可以理解为, struct实例本身就是函数的一个隐藏参数receiver, defer apple.eat(a), 等同 defer eat(apple, a), 也存在apple是值类型,还是指针的情况.

  4. defer的子函数, 是在return a, b; 之后执行的, 也就是如果你的return语句有返回值, 会先对a,b取值, 然后才执行defer的子函数. 那么defer的子函数的执行,是不能影响a,b的值的.

  5. panic时,defer函数也会被执行.

package main

import (
    "fmt"
)

func main() {
    x := TestA()
    fmt.Println(x)
}

func TestA() int {
    a := 1
    b := 2

    defer tt1(&a, &b)
    defer tt2(a, b)

    c := a + b
    a = 5
    if c == 3 {
        panic("TestA")
    }

    return c
}

func tt1(a *int, b *int) {
    fmt.Printf("tt1: %d, %d \n", *a, *b)
}
func tt2(a int, b int) {
    fmt.Printf("tt2: %d, %d \n", a, b)
}
需要 登录 后方可回复, 如果你还没有账号你可以 注册 一个帐号。