一、匿名函数
函数还可以作为返回值,但是在Go语言中不能再像之前那样定义函数了,只能定义匿名函数。匿名函数就是没有函数名的函数。
闭包 = 函数 + 外层变量的引用
一、调用匿名函数的方法
package main
import "fmt"
// 匿名函数与闭包
func main() {
// 将匿名函数保存到变量
add := func(a, b int){
fmt.Println(a + b)
}
add(10, 20) // 通过变量调用匿名函数
// 自执行函数: 匿名函数定义完加()直接执行
func(a, b int){
fmt.Println(a - b)
}(30, 20)
}
二、闭包示例1
package main
import "fmt"
// 闭包 = 函数 + 引用环境
func adder() func(int) int{
var x int
return func(y int) int{
x += y
return x
}
}
func main(){
// f是一个闭包:
// 1. f是一个函数
// 2. f引用了其外部作用域中的x变量
// 在f的生命周期内 变量x一直有效
f := adder()
fmt.Println(f(10))
fmt.Println(f(20))
fmt.Println(f(30))
f1 := adder()
fmt.Println(f1(2000))
fmt.Println(f1(5000))
}
三、闭包示例2
package main
import "fmt"
// 闭包 = 函数 + 外层变量的引用
func adder2(x int) func(int) int{
return func(y int) int{
x += y
return x
}
}
func main(){
f := adder2(0)
fmt.Println(f(10))
fmt.Println(f(20))
fmt.Println(f(30))
f1 := adder2(1000)
fmt.Println(f1(2000))
fmt.Println(f1(5000))
}
四、闭包示例3
package main
import (
"fmt"
"strings"
)
func makeSuffixFunc(suffix string) func(string) string{
return func(name string) string{
if !strings.HasSuffix(name, suffix){
return name + suffix
}
return name
}
}
func main() {
jpgFunc := makeSuffixFunc(".jpg")
txtFunc := makeSuffixFunc(".txt")
fmt.Println(jpgFunc("test")) // test.jpg
fmt.Println(txtFunc("test")) // test.txt
}
五、闭包示例4
package main
import "fmt"
func calc(base int) (func(int) int, func(int) int){
add := func(i int) int{
base += i
return base
}
sub := func(i int) int{
base -= i
return base
}
return add, sub
}
func main(){
f1, f2 := calc(10)
f3, f4 := calc(30)
fmt.Println(f1(1), f2(2)) // 11 9
fmt.Println(f1(3), f2(4)) // 12 8
fmt.Println(f3(5), f4(6)) // 35 29
fmt.Println(f1(5), f2(6)) // 13 7
}
六、panic与recover
package main
import "fmt"
// panic和recover
func a(){
fmt.Println("func a")
}
func b(){
defer func(){
// recover()必须搭配defer使用
// defer必须在可能引发panic的语句之前定义
err := recover()
if err != nil{
fmt.Println("func b error")
}
}()
panic("panic in b")
}
func c(){
fmt.Println("func c")
}
func main() {
a()
b()
c()
}