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