golang函数学习笔记
golang函数特点:
a.不支持重载,一个包不能有两个名字一样的函数
b.函数是一等公民,函数也是一种类型,一个函数可以赋值给变量
c.匿名函数
d.多返回值
例子1
func add(a, b int) int { return a + b } func test1() { fmt.Printf("aaaa") //函数返回值赋值 c := add fmt.Printf("%p %T %p %T\n", c, add, c, add) sum := c(10, 20) fmt.Println(sum) sum = add(10, 20) fmt.Println(sum) }
函数参数传递方式:
1、值传递
2、引用传递
注意:无论是值传递,还是引用传递,传递给函数的都是变量的副本,不过值传递是值的拷贝。引用传递是地址的拷贝,一般来说,地址拷贝更为高效。而值拷贝取决于拷贝的对象大小,对象越大,性能越低。
注意2:map,slice,chan,指针,interface默认以引用的方式传递
例子1
//自定义类型
type add_func func(int, int) int
//自定义函数传递 func operator(op add_func, a int, b int) int { //使用传进来的函数,进行操作 return op(a, b) } func test2() { c := add fmt.Println(c) sum := operator(c, 100, 200) fmt.Println(sum) }
命名返回值的名字:
func add(a,b int)(c int){
c = a+b
return
}
func calc(a,b int)(sum int,avg int){
sum = a+b
avg = (a+b)/2
return
}
这里的返回值都不用谢,已经在函数体中默认定义返回了
_标识符,用来忽略返回值:
func calc(a,b int)(sum int,avg int){
sum = a+b
avg = (a+b)/2
return
}
func main(){
sum,_:= calc(100,200)
}
可变参数表现形式:
func add(arg...int)int{
}
func add(a int,arg...int)int{
}
func add(a int,b int,arg...int)int{
}
注意:其中arg是一个slice(切片),我们可以通过arg[index]依次访问
defer用途:
1.当函数返回时,执行defer语句。因此,可以用来做资源清理
2.多个defer语句,按先进后厨的方式执行
3.defer语句中的变量,在defer声明时就决定了
应用场景:
例子
(1)关闭文件句柄
func read(){
file := open(filename)
defer file.Close()
}
(2)锁资源释放
func read(){
mc.Lock()
defer mc.Unlock()
}
(3)数据看连接释放
递归函数
递归函数的设计原则
1)一个大的问题能够分解成相似的小问题
2)定义好出口条件
例子
//例子四,递归求阶乘 func calc(n int) int { if n == 1 { return 1 } return calc(n-1) * n } func fab(n int) int { //斐波那契数列 if n <= 1 { return 1 } return fab(n-1) + fab(n-2) }
闭包
1、闭包:一个函数与其相关的引用环境组合而成的实体
//闭包的例子 //例子1 func Adder() func(int) int { var x int //匿名函数 f := func(i int) int { x = x + i return x } return f } func testClosure() { f1 := Adder() fmt.Println(f1(10)) fmt.Println(f1(20)) fmt.Println(f1(30)) }
//例子2 func makeSuffixFunc(suffix string) func(string) string { return func(name string) string { if !strings.HasSuffix(name, suffix) { return name + suffix } return name } } func testClosure2() { func1 := makeSuffixFunc(".bmp") func2 := makeSuffixFunc(".jpg") fmt.Println(func1("test")) fmt.Println(func2("test")) }
闭包比较难理解,留个例子后面自己回头再理解一下