一、带多返回值函数有参数 多命名返回值go运行package main import fmt // 有参数、多命名返回值函数求两个数最大最小值 func MaxAndMin(a, b int) (max, min int) { if a b { max a min b } else { max b min a } return // 命名返回值可直接空return自动返回变量值 } func main() { // 接收全部返回值 max, min : MaxAndMin(10, 20) fmt.Printf(max %d, min %d\n, max, min) // 匿名变量 _ 丢弃不需要的返回值 a, _ : MaxAndMin(10, 20) fmt.Printf(最大值a %d\n, a) }核心知识点命名返回值函数头部直接定义返回变量函数内可直接赋值return无需写值多返回值接收变量个数必须和返回值匹配匿名变量_用来舍弃不需要的返回值避免变量未使用报错。二、普通函数调用命名返回值函数go运行package main import fmt // 命名返回值a func funca() (a int) { a 111 fmt.Println(funca a , a) return } func main() { a : funca() fmt.Printf(main a %d, a) }三、递归函数函数调用自身核心规则递归必须设置终止条件否则无限递归栈溢出示例 1递归打印数字理解执行顺序go运行package main import fmt func test(a int) { // 终止条件 if a 1 { fmt.Println(a , a) return } // 递归调用自身 test(a - 1) // 递归回溯时执行 fmt.Println(a , a) } func main() { test(3) fmt.Println(main) }执行流程拆解 test (3)test (3) → 调用 test (2)test (2) → 调用 test (1)test (1)触发终止条件打印a1return回溯执行 test (2) 剩余代码打印a2回溯执行 test (3) 剩余代码打印a3回到 main 打印main输出结果plaintexta 1 a 2 a 3 main示例 2递归实现 1~100 累加求和go运行package main import fmt // 循环实现累加对比递归 func test01() (sum int) { for i : 1; i 100; i { sum i } return } // 递归实现累加 func test02(i int) int { // 递归终止条件 if i 1 { return 1 } // 递推公式当前值 前面所有数的和 return i test02(i-1) } func main() { sum : test02(100) fmt.Println(1~100累加 sum , sum) }递归公式推导sum(n) n sum(n-1)边界sum(1)1四、函数类型函数是一等数据类型知识点Go 中函数属于独立数据类型可以定义变量、赋值、传参type自定义函数类型别名统一规范同类函数签名go运行package main import fmt // 普通加减函数 func Add(a, b int) int { return a b } func Minus(a, b int) int { return a - b } // 自定义函数类型接收两个int返回int type FuncType func(int, int) int func main() { // 方式1直接调用函数 result : Add(1, 1) fmt.Println(result , result) // 方式2函数类型变量接收函数赋值 var fTest FuncType fTest Add result fTest(10, 20) fmt.Println(result2 , result) // 更换函数实现同一个变量调用不同逻辑多态 fTest Minus result fTest(10, 5) fmt.Println(result3 , result) }五、回调函数参数为函数类型核心概念回调函数函数的参数是另一个函数类型主函数内部调用传入的外部函数优势多态特性同一套调用逻辑传入不同函数实现不同功能业务解耦。go运行package main import fmt type FuncType func(int, int) int func Add(a, b int) int { return a b } // Calc 回调函数第二个参数为函数外部传入具体运算逻辑 func Calc(a, b int, fTest FuncType) (result int) { fmt.Println(Calc 统一计算入口) result fTest(a, b) // 执行外部传入的函数 return } func main() { // 将Add函数作为参数传入Calc a : Calc(1, 1, Add) fmt.Println(计算结果a , a) }六、匿名函数 闭包1. 基础概念匿名函数没有函数名的函数可直接定义立即执行或赋值给变量闭包匿名函数捕获外层同作用域变量 / 常量即使脱离外层作用域变量依然保留状态。2. 匿名函数基础用法1定义后立即执行func(){}(参数)go运行package main import fmt func main() { a : 10 str : mike // 无参无返回匿名函数立即执行 func() { fmt.Printf(无参匿名a%d, str%s\n, a, str) }() // 带参数匿名函数立即传参调用 func(i, j int) { fmt.Printf(带参匿名 i%d, j%d\n, i, j) }(10, 20) // 有参有返回值匿名函数 max, min : func(i, j int) (max, min int) { if i j { max i min j } else { max j min i } return }(10, 20) fmt.Printf(匿名函数最值 max%d min%d\n, max, min) }2匿名函数赋值给变量go运行func main() { a : 10 str : mike // 匿名函数赋值变量形成闭包捕获外部变量 f1 : func() { fmt.Printf(捕获外部变量 a%d str%s\n, a, str) } f1() // 调用 }3. 闭包修改外部变量共享引用闭包捕获的是变量引用内部修改会同步改变外层变量go运行func main() { a : 10 str : mike // 闭包修改外部变量 func() { a 666 str go fmt.Printf(闭包内部a %d, str %s\n, a, str) }() fmt.Printf(外层变量a %d, str %s\n, a, str) }4. 闭包核心特性延长局部变量生命周期普通函数局部变量每次调用都会重置闭包会持有外层局部变量多次调用保留变量状态go运行package main import fmt // 普通函数局部变量x每次调用重新初始化 func test01() int { var x int x return x * x } // 返回闭包函数捕获局部变量x func test02() func() int { var x int // 返回匿名闭包 return func() int { x return x * x } } func main() { fmt.Println(普通函数调用) fmt.Println(test01()) //1 fmt.Println(test01()) //1 fmt.Println(test01()) //1 fmt.Println(闭包调用) f : test02() // f持有变量xx不会销毁 fmt.Println(f()) //1 fmt.Println(f()) //4 fmt.Println(f()) //9 fmt.Println(f()) //16 fmt.Println(f()) //25 }原理只要闭包变量f还在使用捕获的局部变量x就不会被 GC 回收持续保存修改后的数值。七、defer 延迟调用1. 基础特性defer只能写在函数内部作用延迟函数调用当前函数执行完毕、return 之前执行多个 defer 遵循后进先出栈结构后定义先执行。示例 1单个 defergo运行package main import fmt func main() { defer fmt.Println(延迟打印 bbbbbbbbbbbbbb) fmt.Println(先执行 aaaaaaaaaaaa) }输出顺序plaintextaaaaaaaaaaaa bbbbbbbbbbbbbb示例 2多个 defer 后进先出go运行func main() { defer fmt.Println(aaaaaaa) defer fmt.Println(bbbbbbb) defer fmt.Println(ccccccccc) }执行顺序ccccccccc → bbbbbbb → aaaaaaa2. defer 匿名闭包组合使用重点defer 定义时立刻拷贝参数值延迟执行时不会读取后续修改go运行package main import fmt func main() { a : 10 b : 20 // 定义defer时直接传入10、20参数值已固定 defer func(x, y int) { fmt.Printf(defer内部a %d, b %d\n, x, y) }(a, b) // 后续修改变量不影响defer内打印 a 111 b 222 fmt.Printf(外部打印a %d, b %d\n, a, b) }输出结果plaintext外部打印a 111, b 222 defer内部a 10, b 20完整知识总结复习速记多返回值函数支持命名返回值_匿名变量丢弃返回值递归必须终止条件先递推再回溯函数类型函数是一等类型type 自定义签名可赋值变量回调函数参数传入函数实现多态、逻辑解耦匿名函数无名称支持定义后立即执行闭包捕获外层变量引用延长局部变量生命周期defer 延迟函数退出前执行多个 defer 后进先出定义时固化参数。