Go语言学习——匿名函数、闭包

匿名函数

匿名函数的定义格式:

func(参数)(返回值){
函数体
}

没有名字的函数

package main

import "fmt"

// 匿名函数

// var f1 = func (x, y int) {
// fmt.Println(x + y)

// }

func main(){
// f1(10, 20)
// 函数内部没有办法声明带名字的函数
// 匿名函数
f1 := func (x, y int) {
fmt.Println(x + y)
}
f1(10, 20)

// 如果只是调用一次的函数,还可以简写成立即执行函数
func (x, y int) {
fmt.Println(x + y)
fmt.Println("Hello world")
} (10, 20)
}

闭包

闭包=函数+引用环境

package main

import "fmt"

// 闭包

func f1(f func()) {
fmt.Println("this is f1")
f()
}

func f2(x, y int) {
fmt.Println("this is f2")
fmt.Println(x + y)
}

// 定义一个函数对f2进行包装
func f3() func() {
tmp := func () {
fmt.Println("Hello")
}
return tmp
}

func test(x int) {
tmp := func () {
fmt.Println(x) // 先在自己这里面找
}
tmp()
}

func test2(x func (int, int), m, n int) {
tmp := func () {
x (m, n)
}
tmp() // x(m, n)
}

func test3(x func(int, int), m, n int) {
x (m, n)
}

func test4(x func (int, int), m, n int) func() {
tmp := func () {
x (m, n)
}
return tmp
}

func main(){
test(100)
test2(f2, 100, 200)
test3(f2, 100, 200)
ret := test4(f2, 100, 200)
ret()
}

一个函数除了用到它内部定义的语句之外还可以引用它外部的变量

package main

import "fmt"

// 闭包

func f1(f func()) {
fmt.Println("this is f1")
f()
}

func f2(x, y int) {
fmt.Println("this is f2")
fmt.Println(x + y)
}

// 要求:
// f1(f2)
func f3(f func(int, int), x, y int) func() {
tmp := func () {
// fmt.Println(x + y)
// f2()
f(x, y)
}
return tmp
}

// 定义一个函数对f2进行包装
// func f3() func() {
// tmp := func () {
// fmt.Println("Hello")
// }
// return tmp
// }

// func test(x int) {
// tmp := func () {
// fmt.Println(x) // 先在自己这里面找
// }
// tmp()
// }

// func test2(x func (int, int), m, n int) {
// tmp := func () {
// x (m, n)
// }
// tmp() // x(m, n)
// }

// func test3(x func(int, int), m, n int) {
// x (m, n)
// }

// func test4(x func (int, int), m, n int) func() {
// tmp := func () {
// x (m, n)
// }
// return tmp
// }

func main(){
// test(100)
// test2(f2, 100, 200)
// test3(f2, 100, 200)
// ret := test4(f2, 100, 200)
// ret()

ret := f3(f2, 100, 200) // 把原来需要传递两个int 类型的参数包装成一个不需要传参的函数
fmt.Printf("%T\n", ret)
f1(ret)
}

闭包 = 函数 + 外部变量的引用

package main

import "fmt"

// 闭包是什么
// 闭包是一个函数,这个函数包含了它外部作用域的一个变量

// 底层的原理:
// 1. 函数可以作为返回值
// 2. 函数内部查找变量的顺序,先在自己内部找,找不到往外层找

func adder(x int) func(int) int {
// var x int
// var x = 100
return func(y int) int {
x += y
return x
}
}
func main() {
// ret := adder()
ret := adder(100)
ret2 := ret(200)
fmt.Println(ret2)

// var f = adder()
// fmt.Println(f(10)) //10
// fmt.Println(f(20)) //30
// fmt.Println(f(30)) //60

// f1 := adder()
// fmt.Println(f1(40)) //40
// fmt.Println(f1(50)) //90
}

闭包例子

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(jpgFunc("test1.jpg")) //test1.jpg
fmt.Println(txtFunc("test")) //test.txt
fmt.Println(txtFunc("test2.txt")) //test2.txt
}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(jpgFunc("test1.jpg")) //test1.jpg
fmt.Println(txtFunc("test")) //test.txt
fmt.Println(txtFunc("test2.txt")) //test2.txt
}

闭包=函数+引用环境

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)
// 修改的是同一个base
fmt.Println(f1(1), f2(2)) //11 9
fmt.Println(f1(3), f2(4)) //12 8
fmt.Println(f1(5), f2(6)) //13 7
}

posted @ 2022-05-14 11:05  寻月隐君  阅读(71)  评论(0)    收藏  举报