有一天我在go的学习交流群中看到这样一段代码
package main
import (
"fmt"
)
func AddFunc()(func(string)string){
base := "hello "
return func(s string) string {
base += s
return base
}
}
func main(){
addc := AddFunc()
fmt.Println(addc("world!"))
fmt.Println(addc("every body!"))
}
本意是想输出:
hello world!
hello every body!
实际输出情况确是:
这是什么原因呢?
首先这是go语言的一个闭包函数,在闭包函数中的变量会随着闭包函数一起被存放在内存中,因此在复制的时候,实际是将函数和变量一起加载到了内存中,即base这个变量其实已经储存在了内存中,如果return 函数对base变量操作并改变了其值,base那块内存的值也会随之改变,第二次在去调用base变量,此时base变量的值已经被改变,在和新的字符串链接。因此就出现了上诉情况。
如果按照该位帅哥的想法,我们需要改变一下代码:
package main
import (
"fmt"
)
func AddFunc()(func(string)string){
base := "hello "
return func(s string) string {
return base + s
}
}
func main(){
addc := AddFunc()
fmt.Println(addc("world!"))
fmt.Println(addc("every body!"))
}
运行结果:
得到了预期结果。
第一种代码其实是非常有用的闭包函数,比如我们写一个斐波拉契数列,或者做一些数据叠加类的处理可以精简代码,可读性更强。