1、定义&调用
1) 定义
函数包含函数名、行参列表、函数体和返回值列表,使用 func 进行声明,函数无参数或返
回值时则形参列表和返回值列表省略
形参列表需要描述参数名及参数类型,所有形参为函数块局部变量。返回值需要描述返回值类型
举例:
a) 无参&无返回值
b) 有参&无返回值
2) 调用
函数通过函数名(实参列表),在调用过程中实参的每个数据会赋值给形参中的每个变量,因此实参列表类型和数量需要函数定义的形参一一对应。针对函数返回值可通过变量赋值的方式接收 s
2、参数
1) 类型合并
在声明函数中若存在多个连续形参类型相同可只保留最后一个参数类型名
2) 可变参数
某些情况下函数需要处理形参数量可变,需要运算符…声明可变参数函数或在调用时传递可变参数
a) 定义
可变参数只能定义一个且只能在参数列表末端。在调用函数后,可变参数则被初始化为对应类型的切片
b) 传递
在调用函数时,也可以使用运算符…将切片解包传递到可变参数函数中
3、返回值
在函数提中可以使用 return 关键字为函数调用这提供函数计算结果
1) 多返回值
go 语言支持函数有多个返回值,在声明函数时使用括号包含所有返回值类型,并使用 return返回对应数量的用逗号分割数据
2) 命名返回值
在函数返回值列表中可指定变量名,变量在调用时会根据类型使用零值进行初始化,在函数体中可进行赋值,同时在调用 return 时不需要添加返回值,go 语言自动将变量的最终结果进行返回在使用命名返回值时,当声明函数中存在若多个连续返回值类型相同可只保留最后一个返回值类型名
4、 递归
递归是指函数直接或间接调用自己,递归常用于解决分治问题,将大问题分解为相同的小问题进行解决,需要关注终止条件
例如:
1) 计算 n 阶乘
n1 = 1 2 3 4 5 … * n
n = 0 => n! = 1
2) 汉罗塔游戏
5、函数类型
函数也可以赋值给变量,存储在数组、切片、映射中,也可作为参数传递给函数或作为函数返回值进行返回
1) 声明&初始化&调用
2) 声明&调用参数类型为函数的函数
6. 匿名函数与闭包
1) 匿名函数
不需要定义名字的函数叫做匿名函数,常用做帮助函数在局部代码块中使用或作为其他函数的参数
2) 闭包
匿名函数有叫闭包, 是指在函数内定义的匿名函数引用外部函数的变量,只要匿名函数继续使用则外部函数赋值的变量不被自动销毁
7. 值类型&引用类型
值类型和引用类型的差异在于赋值同类型新变量后,对新变量进行修改是否能够影响原来的变量,若不能影响则为值类型,若能影响则为引用类型
- 值类型:数值、布尔、字符串、指针、数组、结构体等
- 引用类型:切片、映射、接口等
针对值类型可以借助指针修改原值
针对值类型和引用类型在赋值后新旧变量的地址并不相同,只是引用类型在底层共享数据结构(其中包含指针类型元素)
8. 值传递和引用传递
1) 值传递
在 Go 语言中参数传递默认均为值传递(形参为实参变量的副本),对于引用类型数据因其底层共享数据结构,所以在函数内可对引用类型数据修改从而影响函数外的原变量信息
2) 引用传递
可以通过将变量的地址通过指类型递给函数,此时可通过指针对函数外的原变量进行修改
9. 错误处理
1) error 接口
Go 语言通过 error 接口实现错误处理的标准模式,通过使用函数返回值列表中的最后一个值返回错误信息,将错误的处理交由程序员主动进行处理
error 接口的初始化方法
a) 通过 errors 包的 New 方法创建
b) 通过 fmt.Errorf 方法创建
2) defer
defer 关键字用户声明函数,不论函数是否发生错误都在函数执行最后执行(return 之前),若使用 defer 声明多个函数,则按照声明的顺序,先声明后执行(堆)常用来做资源释放,记录日志等工作
3) panic 与 recover 函数
go 语言提供 panic 和 recover 函数用于处理运行时错误,当调用 panic 抛出错误,中断原有的控制流程,常用于不可修复性错误。recover 函数用于终止错误处理流程,仅在 defer语句的函数中有效,用于截取错误处理流程,recover 只能捕获到最后一个错误
a) panic
b) recover