六、函数
定义:func(p mytype) funcname(q int)(r,s int){ return 0,0 }
p mytype:函数可以定义用于特定的类型,这种函数更加通俗的称呼是method。
递归函数
1 package main 2 3 import ( 4 "fmt" 5 ) 6 7 func rec(i int) { 8 if i == 10 { 9 return 10 } 11 rec(i + 1) 12 fmt.Printf("%d", i) 13 } 14 15 func main() { 16 rec(0) 17 }
9876543210
作用域
1 package main 2 3 var a int 4 5 func main() { 6 a = 5 7 println(a) 8 f() 9 } 10 func f() { 11 //局部变量仅仅在执行定义它的函数时有效 12 a := 6 13 println(a) 14 g() 15 } 16 func g() { 17 println(a) 18 }
结果:
5
6
5
多值返回
1 package main 2 3 var a int 4 5 func main() { 6 a := []byte{'1', '2', '3', '4'} 7 var x int 8 for i := 0; i < len(a); { 9 x, i = nextInt(a, i) 10 println(x) 11 } 12 } 13 14 func nextInt(b []byte, i int) (int, int) { 15 x := 0 16 for ; i < len(b); i++ { 17 x = x*10 + int(b[i]) - '0' //符号0的十进制为48 18 println(x) 19 } 20 return x, i 21 }
结果:
1
12
123
1234
1234
延迟
1 package main 2 3 import ( 4 "fmt" 5 ) 6 7 func main() { 8 for i := 0; i < 5; i++ { 9 //后进先出的顺序执行 10 defer fmt.Printf("%d", i) 11 } 12 fmt.Println(f()) 13 } 14 func f() (ret int) { 15 defer func(x int) { 16 ret++ 17 fmt.Println(x) 18 }(5) //为输入参数x赋值5 自动执行 19 return 0 //返回的是1而不是0 20 }
结果:
5
1
43210
变参
1 package main 2 3 import ( 4 "fmt" 5 ) 6 7 func main() { 8 myfunc(1, 2, 3) 9 myfunc(21, 22) 10 } 11 12 func myfunc(arg ...int) { 13 for v, n := range arg { 14 fmt.Printf("%dIS:%d\n", v, n) 15 } 16 }
0IS:1
1IS:2
2IS:3
0IS:21
1IS:22
函数作为值
1 package main 2 3 import "fmt" 4 5 func main() { 6 a := func() { //定义一个函数,并赋值给a 7 fmt.Println("Hello") 8 } 9 a() 10 fmt.Printf("%T\n", a) 11 var xs = map[int]func() int{ 12 1: func() int { return 10 },//必须有逗号 13 2: func() int { return 20 }, 14 3: func() int { return 30 }, 15 } 16 for v, k := range xs { 17 fmt.Println(v, k) 18 } 19 }
结果:
Hello
func()
2 0x4012fd
1 0x4012db
3 0x40131f
回调
1 package main 2 3 import "fmt" 4 5 func printit(x int) { //函数无返回值 6 fmt.Printf("%v\n", x) 7 } 8 func callback(y int, f func(int)) { 9 f(y) //回转调用 10 } 11 func main() { 12 callback(8, printit) 13 }
结果:8
恐慌(Panic)和恢复(Recover)
Panic >是一个内建函数,可以中断原有的控制流程,进入一个令人恐慌的流程中。当函数F调用panic,函数F的执行被中断,但是F中的延迟函数会正常执行,然后F返回到调用它的地方。在调用的地方,F的行为就像调用了panic。这一过程继续向上,直到发生panic的goroutine中所有调用的函数返回,此时程序退出。恐慌可以直接调用panic产生。也可以由运行时错误产生,例如访问越界的数组。
Recover >是一个内建的函数,可以让进入令人恐慌的流程中的goroutine恢复过来。recover仅在延迟函数中有效。在正常的执行过程中,调用recover会返回nil,并且没有其它任何效果。如果当前的goroutine陷入恐慌,调用recover可以捕获到panic的输入值,并且恢复正常的执行。
1 package main 2 3 import "fmt" 4 5 func fff() { 6 fmt.Println("DGDG") 7 } 8 9 func main() { 10 fmt.Println(throwsPanic(fff)) 11 } 12 13 //定义一个函数接受一个函数作为参数,产生panic就返回true,否则为false 14 func throwsPanic(f func()) (b bool) { 15 //定义一个利用recover的defer函数,如果当前的goroutine产生了panic 16 //这个defer函数能够发现。 17 defer func() { 18 if x := recover(); x != nil { 19 b = true //recover()返回非nil值,设置b为true 20 } 21 }() 22 f() //执行函数f,如果f中出现了panic,那么就可以恢复回来 23 return //返回b 24 }
结果:
DGDG
false
浙公网安备 33010602011771号