六、函数

定义: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。这一过程继续向上,直到发生panicgoroutine中所有调用的函数返回,此时程序退出。恐慌可以直接调用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

posted on 2013-01-31 13:59  liubiaoren  阅读(213)  评论(0)    收藏  举报