go学习笔记2
函数:go里面声明一个函数的基本格式:
func name (参数名 参数类型)返回值类型{ } 例如: func add(x int,y int)int{ return x+y } 如果想要可变参数,就在参数名后加省略号 ,只有最后一个元素可以写成可变参数 func add(x ...int)
在使用可变参数时,得到的参数就是切片类型。
此外,函数可以有多个返回值,将返回值用括号扩起即可。返回值也支持提前命名,函数体内可直接使用。
func test(x int,y int)(int,int){return a,b} func test(x int,y int)(sum int, sub int){return} //二者均可
-------------
自定义函数类型别名:
type test func(int,int)int
此时test就成了一个类型,这个类型是有两个int参数,返回值为int的函数,var a test,a就是函数,可以用a(10,5)这样的方式调用。此时用%T打印a的类型,就会发现是main.test。
但是,如果有一个函数,比如add,直接声明一个变量 a := add,此时a的类型是func(int,int)int。
同样的,go也支持回调,将函数指针作为参数。比如:
func test (x,y int, callback_func func(int,int)int) int {}
这样就定义了test函数,返回值是int。 它的第三个参数叫callback_func,类型是一个函数,包含两个int参数,返回值是int。
同样地,函数也可以作为返回值,返回的是还没有参数的函数,不是直接可进入的函数:
package main type caculate func(int, int)int func do_something(mode string)cauclate{ switch(mode){ case "+": return func(x int,y int)int{
return x+y} case"-": ...... } } //注意返回的是一个函数指针,不是填入参数准备计算的函数 func main(){ var a = caculate("+") fmt.print(a(3,5)) //注意,得到的a要填入参数才能调用
---------- ---------
函数内部可以定义匿名函数,类似lambda表达式。格式和函数差不多:
func (变量类型)(返回值){}
用法也很简单,定义的时候用一个变量保存,然后和普通函数一样,或者定义完直接加上参数括号,立即执行
var a = func(x,y int)int{ return x+y } a(3,5) ------- func(x,y int){ return x+y }(3,5)
------ ---------
闭包:
闭包是指可以访问另一个函数作用域变量的函数。这么说可能比较晦涩,简单来说就是允许一个函数返回一个函数,通过外层函数访问内层函数的局部变量:
func add1() func()int{ var i=10
return func()int{
return i+1
} }
func add2(x int) func(x int)int{
var i=10
return func(x int)int{
i+=x
return i
}
}
此时,如果我们尝试调用内层函数:
import fmt func main(){ var a = add2() //承接到内层函数 fmt.println(a(5)) //15 fmt.println(a(5)) //20 fmt.println(a(5)) //25 }
闭包可以让一个变量常驻内存,但是不污染全局命名。但它不仅仅是一个静态变量的功能。静态变量是固定的,无论在哪里读写都是对这个变量读写。
但闭包是“捕获”了外部作用域的变量,首次获取后就一直存在。并且用不同变量承接,得到的变量会从头开始:
var a = add2() var b = add2() fmt.println(a(5)) //15 fmt.println(a(5)) //20 fmt.println(b(5)) //15
它做到了延迟计算、变量封装,进而可以实现函数工厂、回调等功能。
变量不会被立即销毁影响性能,所以最好只在需要时使用闭包。
浙公网安备 33010602011771号