【Go】Go基础(五):函数

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010168781/article/details/89002374
1、简述

Go 里面有三种类型的函数:

* 普通的带有名字的函数
* 匿名函数或者lambda函数
* 方法(Methods)

两个特殊函数:main()和init(),它们没有参数和返回值;
Go语言里面没有函数重载;

2、函数参数与返回值
* 函数可以返回多值
* 返回值可以和参数一样有个名字:命名的返回值,
	eg:func Fun(in int) (out1 int, out2 int)
* 空白符:下划线_
3、变长参数

格式:

func myFunc(a, b, arg ...int) {}

slice 类型的变量可以通过 slice… 的形式来传递参数

slice := []int{7,9,3,5,1}
x = min(slice...)
4、defer 和代码追踪

defer:收尾工作,

* 关闭文件流
	file, error := os.Open("fineName") 
	defer file.Close()
* 解锁一个加锁的资源
	mu.Lock()  
	defer mu.Unlock() 
* 关闭数据库链接
	// open a database connection  
	defer disconnectFromDB()

代码追踪:利用defer在离开函数时,执行打印操作。

5、内置函数

内置函数:不需要进行导入操作就可以使用的函数

* close		用于管道通信
* len 		用于返回某个类型的长度或数量(字符串、数组、切片、map 和管道)
* cap 		是容量的意思,用于返回某个类型的最大容量(只能用于切片和 map)
* new、make	new 和 make 均是用于分配内存:
	new 	用于值类型和用户定义的类型,如自定义结构,
	make 	用于内置引用类型(切片、map 和管道)
* copy、append		用于复制和连接切片
* panic、recover	两者均用于错误处理机制
* print、println	底层打印函数,建议使用 fmt 包
* complex、real imag	用于创建和操作复数
6、递归函数

递归函数:当一个函数在其函数体内调用自身,则称之为递归.

最经典的例子便是计算斐波那契数列,即前两个数为1,从第三个数开始每个数均为前两个数之和。

数列如下所示:
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, …
计算斐波那契数列的Go源码:

package main

import "fmt"

func main() {
	result := 0
	for i := 0; i <= 5; i++ {
		result = fibonacci(i)
		fmt.Printf("fibonacci(%d) is: %d\n", i, result)
	}
}

func fibonacci(n int) (res int) {
	if n <= 1 {
		res = 1
	} else {
		res = fibonacci(n-1) + fibonacci(n-2)
	}
	return
}

输出:

fibonacci(0) is: 1
fibonacci(1) is: 1
fibonacci(2) is: 2
fibonacci(3) is: 3
fibonacci(4) is: 5
fibonacci(5) is: 8
7、回调

回调:函数可以作为其它函数的参数进行传递,然后在其它函数内调用执行,一般称之为回调

8、闭包

匿名函数可以被赋值给变量并作为值使用;
闭包是匿名函数与匿名函数所引用环境的组合。
没有闭包的时候,函数就是一次性买卖,函数执行完毕后就无法再更改函数中变量的值(应该是内存释放了);有了闭包后函数就成为了一个变量的值,只要变量没被释放,函数就会一直处于存活并独享的状态,因此可以后期更改函数中变量的值(因为这样就不会被go给回收内存了,会一直缓存在那里)
关于闭包的解释,参考下面的博客:
https://blog.csdn.net/qq_35976351/article/details/81986496
https://www.cnblogs.com/cxying93/p/6103375.html
https://blog.csdn.net/jason_cuijiahui/article/details/84720411

利用闭包实现斐波拉契数列

package main

import (
	"fmt"
)

func fibonacci() func() int {
	b0 := 0	//因为b0和b1被返回的匿名函数使用,因此一直在内存中,类似于全局变量,但只能通过myFibonacci函数访问
	b1 := 1
	return func() int {
		tmp := b0 + b1
		b0 = b1
		b1 = tmp
		return b1
	}

}

func main() {
	myFibonacci := fibonacci()
	for i := 1; i <= 5; i++ {
		fmt.Println(myFibonacci())
	}
}
9、打印行号等信息

第一种方法:使用闭包函数where()来实现

where := func() {
	_, file, line, _ := runtime.Caller(1)
	log.Printf("%s:%d", file, line)
}
where()
// some code
where()
// some more code
where()

第二种方法:使用log包来实现:

log.SetFlags(log.Llongfile)
log.Print("")

第三种方法:使用一个更加简短版本的 where 函数:

var where = log.Print
func func1() {
where()
... some code
where()
... some code
where()
}
10、计算函数执行时间
start := time.Now()
longCalculation()
end := time.Now()
delta := end.Sub(start)
fmt.Printf("longCalculation took this amount of time: %s\n", delta)

猜你喜欢

转载自blog.csdn.net/u010168781/article/details/89002374