Golang的匿名函数和闭包

1、匿名函数(anonymous)
匿名函数是一种没有函数名的函数。
在声明匿名函数之后,在其后加上调用的参数列表,即可对匿名函数进行调用
匿名函数有两种调用执行方式:
(1)将匿名函数保存到变量,通过变量执行
(2)自执行匿名函数:在匿名函数后加调用的参数列表"()",即可对匿名函数进行立即调用
 

func main() {
    // 将匿名函数保存到变量
    add := func(x, y int) {
        fmt.Println(x + y)
    }
    add(10, 20) // 通过变量调用匿名函数

    //自执行匿名函数:匿名函数定义完加()直接执行
    func(x, y int) {
        fmt.Println(x + y)
    }(10, 20)
}


2、闭包(Closure)
闭包=匿名函数+引用环境(外层代码定义的变量),即有状态的匿名函数,也可以说:如果匿名函数引用了外部变量,就形成了一个闭包.
在闭包的生命周期内,引用环境即变量也一直有效,会常驻于内存当中
函数本身是不存在信息的,但是闭包中的变量使闭包本身具备了存储信息的能力。

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
}

闭包像go协程一样在for循环时存在延迟绑定的问题

实践:

func main() {
	arr := []float64{1, 9, 16}
	visit(arr, func(v float64) {
		v = math.Sqrt(v)
		fmt.Println("平方根", v)
	})
	visit(arr, func(v float64) {
		v = math.Pow(v, 2)
		fmt.Println("平方", v)
	})

	f2 := makeSuffix(".log")
	fmt.Println(f2("access"))
	fmt.Println(f2("access.log"))
}

// 函数做参数,可以抽象出部分公共逻辑,抽出了循环操作
func visit(lst []float64, f func(float64)) {
	for _, value := range lst {
		f(value)
	}
}

// 函数做返回值,根据不同情形做一件相似的事,检测是否有后缀
func makeSuffix(suffix string) func(string) string {
	return func(name string) string {
		if !strings.HasSuffix(name, suffix) {
			return name + suffix
		}
		return name
	}
}

你可能感兴趣的:(Golang笔记,golang,匿名函数,闭包)