Golong 中的函数
1.基础的函数定义与调用
func getSum(left int, right int) (sum int) {
sum = left + right
return //如果已经在返回值中定义那个sum,这里不需要指出sum
}
x := 20
y := 30
sumCount := getSum(x, y)
fmt.Println(sumCount)
2.函数的参数与返回值问题
//1. 接收动态参数(也可设置动态参数和固定参数)
func intSum2(x ...int) int {
//x是一个int形切片
sum := 0
for _, v := range x {
sum = sum + v
}
return sum
}
ret1 := intSum2()
ret2 := intSum2(10)
ret3 := intSum2(10, 20)
ret4 := intSum2(10, 20, 30)
fmt.Println(ret1, ret2, ret3, ret4) //0 10 30 60
//2. 返回值(如果返回值已经声明,直接写一个return即可)
func calc(x, y int) (sum, sub int) {
sum = x + y
sub = x - y
return
}
pre1 := 300
pre2 := 700
result1, result2 := calc(pre1, pre2)
fmt.Println(result1, result2)
3. 函数的变量作用域
注意点
- 全局变量是定义在函数外部的变量,它在程序整个运行周期内都有效。 在函数中可以访问到全局变量。
- 函数内定义的变量无法在该函数外使用
- 如果局部变量和全局变量重名,优先访问局部变量。
- 在 if 条件判断、for 循环、switch 语句上使用这种定义变量的方式也属于局部变量
4. 高阶函数/匿名函数/立即执行函数
func son(x, y int) int {
return x + y
}
func father(x, y int, op func(int, int) int) int {
return op(x, y)
}
//现有两个函数 嵌套关系(son是father的参数)
//高阶函数测试(函数作为参数或作为)
target := father(10, 20, son)
fmt.Println(target) //30
//匿名函数
base := func(x, y int) int {
return x + y
}
target2 := base(10020, 27) // 通过变量调用匿名函数
fmt.Println(target2)
//立即执行函数1
//又叫自执行函数:匿名函数定义完加()直接执行
func(x, y int) {
fmt.Println(x + y)
}(10, 20)
//立即执行函数2(没参数的)
func() {
fmt.Println("这是一个没有参数的立即执行函数")
}()
6. 闭包问题
func makeSuffixFunc(suffix string) func(string) string {
return func(name string) string {
if !strings.HasSuffix(name, suffix) {
return name + suffix
}
return name
}
}
//闭包函数案例1:
jpgFunc := makeSuffixFunc(".jpg")
txtFunc := makeSuffixFunc(".txt")
fmt.Println(jpgFunc("北京")) //北京.jpg
fmt.Println(txtFunc("天津")) //天津.txt
func calculate(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
}
//闭包函数案例2:
f1, f2 := calculate(10)
fmt.Println(f1(1), f2(2)) //11 9
fmt.Println(f1(3), f2(4)) //12 8
fmt.Println(f1(200), f2(6)) //208 202
//都是基于同一个f1,f2,所以每次对f1 f2的base都会不断更新
f3, f4 := calculate(10)
fmt.Println(f3(1), f4(2)) //11 9
//f3 f4就是基于新的base
//一定要要牢记闭包=函数+引用环境。
7.defer 语句
注意
Go 语言中的 defer 语句会将其后面跟随的语句进行延迟处理。在 defer 归属的函数即将返回时,将延迟处理的语句按 defer 定义的逆序进行执行,也就是说,先被 defer 的语句最后被执行,最后被 defer 的语句,最先被执行。
fmt.Println("start")
defer fmt.Println(1)
defer fmt.Println(2)
defer fmt.Println(3)
fmt.Println("end")
/*
结果是:
start
end
3
2
1
*/
8. 内置函数与错误处理简介,注意是简介
备注
Go 语言中目前是没有异常机制,但是使用 panic/recover 模式来处理错误。 panic 可以在任何地方引发,但 recover 只有在 defer 调用的函数中有效
func funcA() {
fmt.Println("func A")
}
func funcB() {
defer func() {
err := recover()
//如果程序出出现了panic错误,可以通过recover恢复过来
if err != nil {
fmt.Println("recover in B")
}
}()
panic("panic in B")
}
func funcC() {
fmt.Println("func C")
}
funcA()
funcB()
funcC()
/*
结果是:
func A
recover in B
func C
*/