- 什么是闭包?在Go语言中如何实现闭包?
答:闭包是指一个函数和它引用的外部变量构成的实体。在Go语言中,闭包是一个函数值,它可以访问函数体之外声明的变量。在Go语言中实现闭包的方法是,将一个函数和其引用的变量封装在一个结构体中,并返回这个结构体中的函数。
- 下面的代码输出什么?
goCopy code
func main() {
f := foo()
fmt.Println(f())
fmt.Println(f())
}
func foo() func() int {
i := 0
return func() int {
i++
return i
}
}
答:这段代码输出:
Copy code
1
2
解释:foo()
函数返回了一个匿名函数,每次调用该匿名函数时,i
的值都会加一。在 main()
函数中,通过调用 foo()
函数获取该匿名函数,分别调用两次,输出分别为 1
和 2
。
- 闭包和函数的区别是什么?
答:闭包和函数都可以用来封装代码,但闭包可以访问其外部作用域中的变量,而函数只能访问其参数和局部变量。因此,闭包可以用来实现状态的保持,而函数则不能。
- 下面的代码输出什么?
goCopy code
func main() {
f := func() {
fmt.Println("Hello")
}
g := func() {
fmt.Println("World")
}
h := []func(){}
h = append(h, f)
h = append(h, g)
for _, fn := range h {
fn()
}
}
答:这段代码输出:
Copy code
Hello
World
解释:这段代码定义了两个匿名函数 f
和 g
,然后将它们分别添加到一个 []func{}
切片中,最后遍历这个切片并依次调用其中的函数,输出分别为 Hello
和 World
。
- 闭包会引起什么问题?如何避免这些问题?
答:闭包会引起内存泄漏问题,如果一个闭包引用了一个大对象,而该闭包又被长时间持有,那么这个大对象就会被一直占用内存,无法被 GC 回收。为了避免这个问题,可以尽量避免在闭包中引用大对象,或者手动将闭包设置为 nil,以释放其对对象的引用。