zoukankan      html  css  js  c++  java
  • go defer注意点,很容易出错的!!!

    1:defer是在return之前执行的  函数返回的过程是这样的:先给返回值赋值,然后调用defer表达式,最后才是返回到调用函数中

    返回值 = xxx
    调用defer函数
    空的return

    func f() (result int) {
         result = 0  //return语句不是一条原子调用,return xxx其实是赋值+ret指令
         func() { //defer被插入到return之前执行,也就是赋返回值和ret指令之间
             result++
         }()
         return
    }

    func f() (r int) {
         t := 5
         r = t //赋值指令
         func() {        //defer被插入到赋值与返回之间执行,这个例子中返回值r没被修改过
             t = t + 5
         }
         return        //空的return指令
    }

    2:有名返回值和匿名返回值的问题
    匿名返回值是在 return 执行时被声明,有名返回值则是在函数声明的同时被声明,因此在 defer 语句中只能访问有名返回值,而不能直接访问匿名返回值

    此方法返回的是2 而不是1 之前在这困扰了好久,就是没弄明白对匿名返回值的函数是无法修改该返回值的,匿名返回值相当于又重新赋值了一个新的变量

    func det2() int {

        result := 2

        println(&result)

        defer func(result *int) {

            println("det2")

            *result = 1

            println(*result)

        }(&result)#所以对result无论如何修改都无法改变返回值的内容

        #可变形为

       匿名变量 = result

        return 匿名变量 

    }

    相反的 defer修饰的有名返回值的函数可以修改最后的返回值内容
    func b() (i int) {
     defer func() {
      i++
      fmt.Println("b defer2:", i) // 打印结果为 b defer2: 2
     }()
     defer func() {
      i++
      fmt.Println("b defer1:", i) // 打印结果为 b defer1: 1
     }()
     return i // 或者直接 return 效果相同
    }   
    最终返回的结果i为2 ,若果将上述函数变为匿名返回值
     
    func b() {
     defer func() {
      i++
      fmt.Println("b defer2:", i) // 打印结果为 b defer2: 2
     }()
     defer func() {
      i++
      fmt.Println("b defer1:", i) // 打印结果为 b defer1: 1
     }()
     return // 或者直接 return 效果相同
    }  此时返回值为 0


    3:defer 调用的函数参数的值在 defer 定义时就确定了, 而 defer 函数内部所使用的变量的值需要在这个函数运行时才确定
    func f1() (r int) {
        r = 1
        defer func() {
            r++
            fmt.Println(" r value = ",r)
        }()
        r = 2
        return
    }



    参考:https://www.jb51.net/article/127130.htm
  • 相关阅读:
    org.springframework.transaction.CannotCreateTransactionException Could not open
    org.springframework.web.util.NestedServletException Handler processing failed; n
    SSM 后台封装的有值, 到前台打印的时候没有值
    javax.net.ssl.SSLHandshakeException sun.security.validator.ValidatorException PK
    a 链接点击下载
    form图片上传遇到错误
    forever 启动nodejs
    nodejs 新建项目
    nodejs 安装
    nodejs 爬虫模板 map&array 数据模型
  • 原文地址:https://www.cnblogs.com/fly-kaka/p/10172587.html
Copyright © 2011-2022 走看看