Function Golang在编写函数闭包时是否自动将变量指定为参数?

Function Golang在编写函数闭包时是否自动将变量指定为参数?,function,go,closures,Function,Go,Closures,以下是我指的代码: 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.Prin

以下是我指的代码:

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),
        )
    }
}
我不知道在
adder
函数的
return
语句中如何分配
x
?它似乎没有在函数中的任何位置传递。
我也不知道
sum
变量是如何工作的。每次调用函数
adder
并为其赋值
0

赋值时,
sum
变量都在两个闭包中。
pos
闭包中的
sum
通过添加1、2、3、4(斐波那契风格)进行更新,而
neg
闭包中的
sum
通过在每个循环迭代中减去2*1、2*2、2*3、2*4进行更新

或者,更详细地说:
pos:=adder()
分配给
pos
一个函数,该函数在
sum
上有一个闭包,其中
sum
是0开始。然后,无论何时调用函数
pos
,它都会相应地更新
sum
。对于
neg
,以及任何其他类似的赋值,情况也完全相同

下面是一些类似的(更简单的)JavaScript代码,可以在浏览器控制台中运行:

function adder() {
  var sum = 0;
  return function(i) {
    sum += i;
    return sum;
  }
}

var pos = adder();
console.log( pos(1) ); // add 1 to 0 (1)
console.log( pos(2) ); // add 2 to 1 (3)
console.log( pos(3) ); // add 3 to 3 (6)
console.log( pos(4) ); // add 4 to 6 (10)
以下是JavaScript中闭包的一些背景信息:


希望这有帮助。

当您分配
pos
neg
时,
sum
变量位于两个闭包中的每个闭包内。
pos
闭包中的
sum
通过添加1、2、3、4(斐波那契风格)进行更新,而
neg
闭包中的
sum
通过在每个循环迭代中减去2*1、2*2、2*3、2*4进行更新

或者,更详细地说:
pos:=adder()
分配给
pos
一个函数,该函数在
sum
上有一个闭包,其中
sum
是0开始。然后,无论何时调用函数
pos
,它都会相应地更新
sum
。对于
neg
,以及任何其他类似的赋值,情况也完全相同

下面是一些类似的(更简单的)JavaScript代码,可以在浏览器控制台中运行:

function adder() {
  var sum = 0;
  return function(i) {
    sum += i;
    return sum;
  }
}

var pos = adder();
console.log( pos(1) ); // add 1 to 0 (1)
console.log( pos(2) ); // add 2 to 1 (3)
console.log( pos(3) ); // add 3 to 3 (6)
console.log( pos(4) ); // add 4 to 6 (10)
以下是JavaScript中闭包的一些背景信息:


希望这能有所帮助。

Go以一种非常典型/标准的方式处理一流的函数和闭包。有关一般闭包的良好背景,请参阅。在这种情况下,调用加法器本身:

  • 使用值
    0
    创建名为
    sum
    int
    对象
  • 返回一个闭包:一个类似thingy1的函数,调用该函数时可以访问变量
    sum
  • 像thingy这样的特殊函数,其
    加法器
    返回,调用程序在普通变量中捕获,它是一个接受一个参数的函数。然后调用它,传递一个参数。这个论点的通过没有什么特别之处:它的工作方式与其他任何地方一样。在类似thingy的函数中,使用变量
    x
    获取调用者传递的值。使用名称
    sum
    获取捕获的
    int
    对象,无论其值是什么。从函数返回时,捕获的
    int
    仍被捕获,因此稍后对同一函数(如thingy)的调用会在
    sum
    中看到更新的
    int

    通过两次调用
    加法器
    ,您可以得到两个稍有不同的函数,如thingies:每个函数都有自己的私有
    。这两个私有
    sum
    s最初都为零。调用像thingy这样的函数(其值已保存在
    pos
    中)可以获得使用其中一个函数的函数。调用稍有不同的函数,比如thingy,它的值保存在
    neg
    中,可以得到使用另一个函数的函数


    1“类似thingy的函数”与实际函数之间没有真正的区别,只是类似thingy的特定函数没有可供调用的名称。这或多或少就是拥有一流功能的含义


    如果你在可读性问题上陷入困境。。。 其原始形式为:

    func adder() func(int) int {
        sum := 0
        return func(x int) int {
            sum += x
            return sum
        }
    }
    
    让我们用一些类型名和其他语法更改来重写它,使代码的核心保持不变。首先,让我们创建一个表示
    func(int)int
    的名称:

    type adderClosure func(int) int
    
    然后我们可以用它重写加法器的第一行:

    func adder() adderClosure {
        ...
    }
    
    现在让我们在加法器中创建一个局部变量来保存我们要返回的函数。为了明确和冗余,我们可以再次使用此类型:

        var ret adderClosure // not good style: just for illustration
    
    现在,让我们通过以下操作将该变量分配给闭包:

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

    然后我们可以
    返回ret
    来返回闭包

    Go以非常典型/标准的方式处理一流函数和闭包。有关一般闭包的良好背景,请参阅。在这种情况下,调用加法器本身:

  • 使用值
    0
    创建名为
    sum
    int
    对象
  • 返回一个闭包:一个类似thingy1的函数,调用该函数时可以访问变量
    sum
  • 像thingy这样的特殊函数,其
    加法器
    返回,调用程序在普通变量中捕获,它是一个接受一个参数的函数。然后调用它,传递一个参数。这个论点的通过没有什么特别之处:它的工作方式与其他任何地方一样。在类似thingy的函数中,使用变量
    x
    获取调用者传递的值。使用名称
    sum
    获取捕获的
    int
    对象,无论其值是什么。从函数返回时,捕获的
    int
    仍被捕获,因此稍后对同一函数(如thingy)的调用会在
    sum
    中看到更新的
    int

    通过两次调用
    加法器
    ,您可以得到两个稍微不同的函数,如thingies:每个函数都有自己的私有