js,python,golang
python
def make_adder(addend):
    def adder(augend):
        return augend + addend
    return adder
golang
func outer(x int) func(int) int{
    func inner(y int) int{
        return x + y
    }
    return inner
}
golang
package main
 
import (
    "fmt"
)
 
func outer(x int) func(int) int {
    return func(y int) int {
        return x + y 
    }   
}
 
func main() {
    f := outer(10)
    fmt.Println(f(100))
} 
golanggolang

1,for range 中使用闭包

一个示例:

func main() {                
    s := []string{"a", "b", "c"}                             
    for _, v := range s { 
        go func() {
            fmt.Println(v)
        }()                 
    }                        
    select {}    // 阻塞模式                                                         
}                          

// 嗯,结果应该是 a,b,c 吧

来看看结果:

输出的结果不期而然,大家的结果也不一定和我相同。

对比下面的改进:

func main() {                
    s := []string{"a", "b", "c"}                             
    for _, v := range s { 
        go func(v string) {
            fmt.Println(v)
        }(v)   //每次将变量 v 的拷贝传进函数                 
    }                        
    select {}                                                      
}  

所以结果当然是:

"a"
"b"
"c"
go
v

2,函数列表使用不当

package main

import (
    "fmt"
)

func test() []func() {
    var s []func()

    for i := 0; i < 3; i++ {
        s = append(s, func() {  //将多个匿名函数添加到列表
            fmt.Println(&i, i)
        })
    }

    return s    //返回匿名函数列表
}
func main() {
    for _, f := range test() {  //执行所有匿名函数
        f()   
    }
}

运行结果:

解决方法:

package main

import (
    "fmt"
)

func test() []func() {
    var s []func()
    
    for i := 0; i < 3; i++ {
        x := i                  //复制变量
        s = append(s, func() {
            fmt.Println(&x, x)
        })
    }

    return s
}
func main() {
    for _, f := range test() {
        f()
    }
}
appendiiiii

若是你对闭包理解了,也可以利用闭包来修改全局变量:

package main                   
                               
import (                       
    "fmt"                      
)                              
                               
var x int = 1                  
                               
func main() {                  
    y := func() int {          
        x += 1                 
        return x               
    }()                        
    fmt.Println("main:", x, y)                                                            
} 

// 结果:    main: 2 2

3,延迟调用

deferdefer
package main

import "fmt"

func main() {
    x, y := 1, 2

    defer func(a int) { 
        fmt.Printf("x:%d,y:%d\n", a, y)  // y 为闭包引用
    }(x)      // 复制 x 的值

    x += 100
    y += 100
    fmt.Println(x, y)
}

输出结果:

101 102
x:1,y:102
bug