函数
函数是一段可重复使用的代码段
func fn_name(params-list)(return-list){body}
在go语言中,函数的四要素:
函数名,
参数列表
返回值列表
函数体
与其他语言函数显著的不同点在于,go语言中的函数允许多个返回值.
函数名
没有函数名的函数称之为匿名函数,匿名函数通常用在只执行一次的场景.
函数递归
函数可以递归,这意味着函数可以直接或间接的调用自己,
func main() {res := sum(100)fmt.Println(res)}func sum(num int) int {if num > 0 {return num + sum(num-1)} else {return 0}}
思考,这种写法有什么弊端,若原函数名被修改,是否会造成不能找到原函数,该问题如何解决呢?
函数参数
go语言中的参数不支持默认值,多个相邻参数类型且相同时可进行简写
不定参数
所有函数的参数都是按照值进行传递的.
函数变量
在go语言中函数被设计为头等公民.
在变成语言设计中,一个实体如果支持所有通常对其他实体可用的操作,那么这个实体就被认为是一等公民,这些操作包括赋值给变量,作为参数传递,作为返回值返回.
将函数赋值给变量
更重要的是,以这种方式定义的函数能够获取到整个词法环境,因此里层函数可以访问外层函数中的变量,一直到当前文件的最外层,如果还是没有找到则会报错.
函数类型的零值是nil,调用一个空的函数变量将导致宕机.
作为参数传递给函数
作为返回值
匿名函数
命名函数只能在包级别作用域进行声明
函数参数
go语言中的函数参数不能设置默认值.
在函数定义时有形参,在调用函数时必须传递.
参数简写
多个相邻参数且类型相同时,可简化书写.
变长参数
经常使用的fmt.Println()为什么接收任意个参数呢?
func Println(a ...any) (n int, err error) {return Fprintln(os.Stdout, a...)}
在参数列表最后的类型名称钱使用省略号...,表示声明一个变长函数,调用这个函数的时候可以传递该类型任意数目的参数.
func main() {res1 := sum(1, 2)res2 := sum(1, 2, 3)res3 := sum(1, 2, 3, 4, 5)fmt.Println(res1, res2, res3)}func sum(nums ...int) int {total := 0for _, num := range nums {total += num}return total}
变长参数有且只能有一个,位于函数的最后一个参数.
变长参数在函数内是类似slice,在需要遍历的场景,可将其当作slice来用
需要注意的是变长函数的类型和一个带有普通slice参数的函数的类型是不同的.
函数的延迟调用--defer
通常用于关闭系统资源,
按照defer的注册顺序,先注册的后执行,类似于
defer后跟函数调用,或方法调用.
错误处理
panic,触发一个运行时错误,至到遇到recover或程序终止.