golang笔记——函数与方法
2016-03-27 21:54
232 查看
如果你遇到没有函数体的函数声明,表示该函数不是以Go实现的。
匿名函数和squares中,存在变量引用。这就是函数值属于引用类型和函数值不可比较的原因。Go使用闭包(closures)技术实现函数值,Go程序员也把函数值叫做闭包。注意golang圣经中匿名函数一节中的例子程序。go语言的可变参函数非常好用,你可以传递多个同类型参数,也可以直接传入一个该类型的切片(注意传入切片时要使用...标记,我想应该是为了同切片参数区分吧,毕竟两者还是有些不同的),如果想要使用不同类型的变参,那么使用万能的interfac{},函数体内像解析切片一样解析这个变参就好了。直到包含该defer语句的函数执行完毕时,defer后的函数才会被执行,不论包含defer语句的函数是通过return正常结束,还是由于panic导致的异常结束。你可以在一个函数中执行多条defer语句,它们的执行顺序与声明顺序相反
我们只需要首先命名double的返回值,再增加defer语句,我们就可以在double每次被调用时,输出参数以及返回值。
太利于调试了。。。defer语句还是要细看。为了方便诊断问题,runtime包允许程序员输出堆栈信息。在下面的例子中,我们通过在main函数中延迟调用printStack输出堆栈信息。
packagemath funcSin(xfloat64)float//implementedinassemblylanguage
如果为函数的每一个返回值都设置变量名,则会以相应的零值初始化,且在该函数的return语句中省略操作数,这种用法称之为barereturn。 go中的错误处理,习惯上是先进行一系列的初始化检查,将处理失败逻辑的代码先行处理,然后才是函数的实际逻辑,这样使得代码更简洁,避免过多的层级结构。 函数定义时,可以使用函数类型作为参数,也可以作为返回类型,是不是有点类似委托,从而实现闭包。此外还有匿名函数,是不是类似于lambda表达式。strings.Map函数可以拿来试验。
funcsquares()func()int{ varxint returnfunc()int{ x++ returnx*x } } funcmain(){ f:=squares() fmt.Println(f())//"1" fmt.Println(f())//"4" fmt.Println(f())//"9" fmt.Println(f())//"16" }
匿名函数和squares中,存在变量引用。这就是函数值属于引用类型和函数值不可比较的原因。Go使用闭包(closures)技术实现函数值,Go程序员也把函数值叫做闭包。注意golang圣经中匿名函数一节中的例子程序。go语言的可变参函数非常好用,你可以传递多个同类型参数,也可以直接传入一个该类型的切片(注意传入切片时要使用...标记,我想应该是为了同切片参数区分吧,毕竟两者还是有些不同的),如果想要使用不同类型的变参,那么使用万能的interfac{},函数体内像解析切片一样解析这个变参就好了。直到包含该defer语句的函数执行完毕时,defer后的函数才会被执行,不论包含defer语句的函数是通过return正常结束,还是由于panic导致的异常结束。你可以在一个函数中执行多条defer语句,它们的执行顺序与声明顺序相反
varmusync.Mutex varm=make(map[string]int) funclookup(keystring)int{ mu.Lock() defermu.Unlock() returnm[key] }调试复杂程序时,defer机制也常被用于记录何时进入和退出函数。[/code]
funcbigSlowOperation(){ defertrace("bigSlowOperation")()//don'tforgetthe extraparentheses //...lotsofwork… time.Sleep(10*time.Second)//simulateslow operationbysleeping } functrace(msgstring)func(){ start:=time.Now() log.Printf("enter%s",msg) returnfunc(){ log.Printf("exit%s(%s)",msg,time.Since(start)) } }[/code]
我们只需要首先命名double的返回值,再增加defer语句,我们就可以在double每次被调用时,输出参数以及返回值。
funcdouble(xint)(resultint){ deferfunc(){fmt.Printf("double(%d)=%d\n",x,result)}() returnx+x } _=double(4) //Output: //"double(4)=8"
太利于调试了。。。defer语句还是要细看。为了方便诊断问题,runtime包允许程序员输出堆栈信息。在下面的例子中,我们通过在main函数中延迟调用printStack输出堆栈信息。
gopl.io/ch5/defer2不能为一个结构体定义同名的字段名和方法名,有点奇怪。[/code]
funcmain(){
deferprintStack()
f(3)
}
funcprintStack(){
varbuf[4096]byte
n:=runtime.Stack(buf[:],false)
os.Stdout.Write(buf[:n])
}
函数指针:go里其实也是有函数指针的,下面用go语言实现表驱动模式。
packagemainimport(
"fmt"
)funcadd(aint,bint)int{
returna+b
}funcsub(aint,bint)int{
returna-b
}funcmain(){
fm:=make(map[int]func(int,int)int)
fm[1001]=add
fm[1002]=sub
protocol:=2001
i:=1
j:=2
iffunc_handle,ok:=fm[protocol];ok{
println(func_handle(i,j))
}else{
fmt.Printf("protocol:%dnotregister!",protocol)
}
}
相关文章推荐
- HDU Let's go to play
- 如何在 Google 地图中添加标记和说明
- 启动Genymotion模拟器时,显示The virtual device got no IP address
- gone fishing
- HDU--1533--Going Home--KM算法
- Go语言学习(九)文件操作
- 【Algorithm】选择排序法
- 初识google多语言通信框架gRPC系列(二)编译gRPC
- Google Test
- EM算法(Expectation Maximization Algorithm)
- Google Maps API3 之 Hello World
- 搭建golang环境
- LeetCode Algorithms #107 <Binary Tree Level Order Traversal II>
- LeetCode OJ 之Merge TwoSorted Lists 解题报告
- LeetCode OJ 之 GenerateParenthesis解题报告
- 教程: Windows 7、Vista 开启ipv6支持
- 英文歌曲:my heart will go on(我心永恒)
- 文本分类与聚类(text categorization and clustering)
- Golang给目录按时间排序.正则、时间条件搜索文件
- google hosts(2)