为何在循环调用中,sum只被初始化了一次?

为何在循环调用中,sum只被初始化了一次?

package main

import "fmt"

func adder() func(int) int {
    sum := 0
    return func(x int) int {
        sum += x
        return sum
    }
}

func main() {
    pos, neg := adder(), adder()
    for i := 0; i < 10; i++ {
        fmt.Println(
            pos(i),
            neg(-2*i),
        )
    }
}

其中:

sum := 0
    return func(x int) int {
        sum += x
        return sum
    }

匿名函数引用外部变量,形成闭包.sum是有记忆功能的.可是在函数adder()中

func adder() func(int) int {
    sum := 0
    return func(x int) int {
        sum += x
        return sum
    }
}

sum,是函数的内部变量,在循环中累次调用adder()函数.不应该是每调用一次,sum就被初始化一次么?这样就不能实现累加了.
按照程序运行的结果看,实现了累加,在循环调用中,sum并没有每次都被初始化.这是为什么?是go语言的语法规则么?我在课程中并没有听到类似的规则.

正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

1回答
ccmouse 2021-12-28 19:13:13

adder函数只调用了2次,在pos, neg := adder(), adder()

所以sum只被初始化两次,一次用来累加正数,一次用来累加负数。

后面我们循环调用的是pos, neg函数,不是adder函数。

pos, neg函数的函数体是:

        sum += x
        return sum

没有初始化sum。“匿名函数引用外部变量,形成闭包.sum是有记忆功能的。”这句话说的是对的。其中“记忆功能”并不特殊,每个变量只要没有初始化都有“记忆功能”。

  • 提问者 AT路遥 #1
    pos, neg := adder(), adder()

    谢谢老师,懂了,还有个疑问.sum只被初始化了2次.从运行结果来看,两个sum是互相不干涉的,这是因为变量的作用域么?说实话,又是匿名函数,又是闭包的,有点迷糊.


    2022-01-06 14:57:01
  • ccmouse 回复 提问者 AT路遥 #2

    把匿名函数当成一个普通的像int, string那样的变量就好理解了。调用了两次adder函数,所以sum被初始化了两次,两个sum互不相干。

    2022-01-16 10:50:37
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师