Go基础---->go的基础学习(二)
这里记录的是go中函数的一些基础知识。道听途说终是浅,身临其境方知深。
go的基础知识
一、go中函数的基础使用
package main import ( "fmt" "errors" ) func add(a int, b int) (ret int, err error) { if a < 0 || b < 0 { err = errors.New("Should be non-negative numbers!") return } return a + b, nil } // 不定参数类型 func myFunc(args ...int) int { var result int for _, arg := range args { result += arg } return result } func main() { result, err := add(3, 4) fmt.Println(result, err) // 7 <nil> fmt.Println(add(-1 ,34)) // 0 Should be non-negative numbers! fmt.Println(myFunc(1, 3, 5, 7)) // 16 }
二、go中的关于匿名函数的使用
package main import "fmt" func main() { // 匿名函数赋值给一个变量 f := func (x, y int) int { return x + y } fmt.Println(f(3, 45)) // 48 // 匿名函数直接执行 var result = func (x, y int) int { return x - y }(45, 6) fmt.Println(result) // 39 }
三、go中闭包的使用
Go的匿名函数是一个闭包,闭包是可以包含自由(未绑定到特定对象)变量的代码块,这些变量不在这个代码块内或者任何全局上下文中定义,而是在定义代码块的环境中定义。
一个比较好的例子可以参考一下:http://blog.csdn.net/u012296101/article/details/48525605
package main import "fmt" func adder() func(int) int { sum := 0 return func (x int) int { fmt.Println(">>>>>", sum) sum += x return sum } } func main() { pos, neg := adder(), adder() for i := 0; i < 10; i++ { fmt.Println(pos(i), neg(-2 * i)) } }
运行的效果如下:
>>>>> 0 >>>>> 0 0 0 >>>>> 0 >>>>> 0 1 -2 >>>>> 1 >>>>> -2 3 -6 >>>>> 3 >>>>> -6 6 -12 >>>>> 6 >>>>> -12 10 -20 >>>>> 10 >>>>> -20 15 -30 >>>>> 15 >>>>> -30 21 -42 >>>>> 21 >>>>> -42 28 -56 >>>>> 28 >>>>> -56 36 -72 >>>>> 36 >>>>> -72 45 -90
四、go中的defer关键字
package main import ( "fmt" ) func main() { defer fmt.Println("before execute") fmt.Println("my name is LL.") defer fmt.Println("after execute") }
运行的结果:
my name is LL. after execute before execute
defer函数调用被压入一个栈中。当函数返回时, 会按照后进先出的顺序调用被延迟的函数调用。
五、panic() 和 recover()的函数
package main import ( "fmt" ) // 最简单的例子 func SimplePanicRecover() { defer func() { if err := recover(); err != nil { fmt.Println("Panic info is: ", err) } }() panic("SimplePanicRecover function panic-ed!") } // 当 defer 中也调用了 panic 函数时,最后被调用的 panic 函数的参数会被后面的 recover 函数获取到 // 一个函数中可以定义多个 defer 函数,按照 FILO 的规则执行 func MultiPanicRecover() { defer func() { if err := recover(); err != nil { fmt.Println("Panic info is: ", err) } }() defer func() { panic("MultiPanicRecover defer inner panic") }() defer func() { if err := recover(); err != nil { fmt.Println("Panic info is: ", err) } }() panic("MultiPanicRecover function panic-ed!") } // recover 函数只有在 defer 函数中被直接调用的时候才可以获取 panic 的参数 func RecoverPlaceTest() { // 下面一行代码中 recover 函数会返回 nil,但也不影响程序运行 defer recover() // recover 函数返回 nil defer fmt.Println("recover() is: ", recover()) defer func() { func() { // 由于不是在 defer 调用函数中直接调用 recover 函数,recover 函数会返回 nil if err := recover(); err != nil { fmt.Println("Panic info is: ", err) } }() }() defer func() { if err := recover(); err != nil { fmt.Println("Panic info is: ", err) } }() panic("RecoverPlaceTest function panic-ed!") } // 如果函数没有 panic,调用 recover 函数不会获取到任何信息,也不会影响当前进程。 func NoPanicButHasRecover() { if err := recover(); err != nil { fmt.Println("NoPanicButHasRecover Panic info is: ", err) } else { fmt.Println("NoPanicButHasRecover Panic info is: ", err) } } // 定义一个调用 recover 函数的函数 func CallRecover() { if err := recover(); err != nil { fmt.Println("Panic info is: ", err) } } // 定义个函数,在其中 defer 另一个调用了 recover 函数的函数 func RecoverInOutterFunc() { defer CallRecover() panic("RecoverInOutterFunc function panic-ed!") } func main() { SimplePanicRecover() MultiPanicRecover() RecoverPlaceTest() NoPanicButHasRecover() RecoverInOutterFunc() }
运行的结果如下:
Panic info is: SimplePanicRecover function panic-ed! Panic info is: MultiPanicRecover function panic-ed! Panic info is: MultiPanicRecover defer inner panic Panic info is: RecoverPlaceTest function panic-ed! recover() is: <nil> NoPanicButHasRecover Panic info is: <nil> Panic info is: RecoverInOutterFunc function panic-ed!
可以参考博客:http://www.cnblogs.com/ghj1976/archive/2013/02/11/2910114.html
友情链接
作者:
huhx
出处: www.cnblogs.com/huhx
格言:你尽力了,才有资格说自己的运气不好。
版权:本文版权归作者huhx和博客园共有,欢迎转载。未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。
出处: www.cnblogs.com/huhx
格言:你尽力了,才有资格说自己的运气不好。
版权:本文版权归作者huhx和博客园共有,欢迎转载。未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。