Golang函数
函数是Golang中的一个基本概念,用于完成特定的功能,由以下几部分组成
func 函数名 (参数列表) (返回值俩表) {
函数体
}
函数的定义以关键字func开头,接着是函数名,参数列表,返回值列表,最后是函数体
函数的参数
函数的参数列表由形参和实参组成。形参是函数定义中的参数,是函数签名中的一部分,与变量的定义类似,在函数调用时,形参将被赋予实参的值,如:
func add(a,b int) int {
return a+b
}
该函数中 a和b就是形参
result := add(2,3) 其中2和3为实参
需要注意的是,Golang函数的参数传递是值传递,也就是说函数内部会创建一个变量,将实参的值复制给这个变量,然后对这个变量进行操作。因此,在函数内部修改参数值并不会影响到函数外面的变量值。
函数的返回值
函数的返回值是函数执行完成后的结果,返回值可以有一个或者多个,也可以没有
func netinfo (a,b string)(x,y string){
return x,y
}
函数的作用域
函数内部定义的变量只在函数内部有效,外部不能访问函数内部的变量,同时,在Golang中,函数也可以调用外部的变量和函数,但是,变量和函数调用的作用域只能在函数内部
var x int =0
func add (y int) int {
return x+y
}
该例子中x为全局变量,函数add调用时可以访问x,但这只是因为x的作用域覆盖了函数的作用域,而函数中定义的变量y只在函数内部有效。
可变长参数列表
在某些情况下,函数的参数列表可能不确定,这时就可以使用可编程参数列表,用…表示,如:
func sum(nums ...int){
total :=0
for _,num := range nums {
total += num
}
fmt.Println(total)
}
函数的高级用法
定义函数
可以使用type关键字来声明一个函数类型,如
type cal func(int,int) int
func add(x,y int) int {
return x+y
}
func sub(x,y int) int {
return x-y
}
var f cal
f = add
res :=f(10,5)
函数可以作为其他函数的参数
func f(x,y int,op func(int,int) int) int {
return op(x,y)
}
res := f(10,5,add)
函数作为返回值
func cal (op string) func(int,int) int {
switch op {
case "add":
return add
case "sub":
return sub
default:
return nil
}
}
f :=cal("sub")
if f !=nil {
ret :=f(10,5)
}
匿名函数
Go 语言中,在函数内部无法再次定义函数,因此想要实现函数的嵌套,必须借助匿名函数。所谓匿名函数,即没有函数名的函数,没办法像普通函数那样调用,所以匿名函数需要保存到某个变量或者作为立即执行函数。匿名函数多用于实现回调函数和闭包。
add := func(x,y int) int {
return x+y
}
add(10,5)
func(x,y int) int{
return x+y
}(10,5)
defer语句
在GoLang中,defer语句用于在函数执行完成后执行一个或多个语句,这些语句将会在函数返回值之前执行,如:
file,err :=os.Open("a.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close() defer用于关闭文件,保证在函数返回之前文件被正确关闭。
// 读取文件内容并操作
如果有多个 defer
,按定义的逆序进行执行,也就是说,先被 defer
的语句最后被执行,最后被 defer
的语句,最先被执行。
闭包
闭包是一个函数与其他行管的引用环境的组合,简单说,闭包就是让一个函数拥有自己的作用域,在golang中,可以使用闭包来在函数之间共享变量。
func counter() func() int {
i :=0
return func() int {
i++
return i
}
}
在这个例子中,counter函数返回一个匿名函数,这个函数会在每次被调用时增加i的值并返回新的i。
panic/recover
Go 语言中常常使用 panic/recover 模式来处理代码中的异常场景, panic 可以在任何地方引发,但 recover 只有在 defer 调用的函数中有效,因此 recover() 必须搭配 defer 使用,且 defer 一定要在可能引发 panic 的语句之前定义。
func A() {
fmt.Println("function A")
}
func B() {
panic("panic in function B")
}
func C() {
fmt.Println("function C")
}
A()
B()
C()
上述代码会引发 panic ,程序崩溃,异常退出:
可以通过 recover 将程序恢复回来,继续往后执行:
func B() {
defer func(){
err := recover()
//如果程序出出现了panic错误,可以通过recover恢复过来
if err != nil {
fmt.Println("recover in function B")
}
}()
panic("panic in function B")
}