# 函数
所有函数都是全局函数,可以被项目中其他文件使用,在项目中函数名唯一。
全局变量作用域是项目中所有文件
全局变量和 const 在内存中的**数据区**存储。
变量在栈区存储。
函数在代码区存储。
## 定义
```go
func name(a argv) {
...
}
```
## 不定参数函数
```go
func test(argvs ...int) {
...
}
```
> 参数传递前需要解析
### 不定参数传递实例
~~~go
package main
import "fmt"
func test(argvs ...int) {
test2(argvs[:]...)
}
func test2(argvs ...int) {
fmt.Println(argvs)
}
func main() {
test(1,2,3)
}
~~~
## 函数返回值
return 表示函数结束
~~~go
func test(argvs ...int) (ret []int){
test2(argvs[:]...)
return argvs
}
~~~
## 函数类型
省略函数名和函数参数名
## 匿名函数
不能在函数中在定义一个函数,在函数中可以定义匿名函数。
~~~
func main() {
// 匿名函数,定义的时候直接调用
func(a int, b int) {
c := a + b
fmt.Println(c)
}(1, 2)
}
~~~
或者
~~~go
func main() {
// 匿名函数,先定义后调用
f := func(a int, b int) (c int) {
c = a + b
return
}
fmt.Println(f(1, 2))
}
~~~
## 闭包
所谓闭包就是有权利访问另一个函数作用域中的变量,就是在一个函数中创建另一个函数。闭包实际上是匿名函数的应用。
因为不能在函数中声明另一个函数,但是可以在函数中声明一个函数类型的变量,此时的函数成为闭包(closure)。
### 使用匿名函数的情形
~~~go
func main() {
//变量f存储在栈区,只有在 main 函数结束后,变量 f 才会被释放
var a int
f := func(b int) int {
a++
return a+b
}
for i:=0; i<5; i++{
fmt.Println(f(3))
}
}
~~~
### 通过闭包的形式改造
~~~go
func main() {
//变量f存储在栈区,只有在 main 函数结束后,变量 f 才会被释放
f := closure()
for i:=0; i<5; i++{
fmt.Println(f(3))
}
}
func closure() func(b int) int{
var a int
return func(b int) int {
a++
return a+b
}
}
~~~
### 闭包--保存一些环境或者基础变量
~~~
func main() {
//变量f存储在栈区,只有在 main 函数结束后,变量 f 才会被释放
f := realPrice(10)
fmt.Println(f(9))
fmt.Println(f(8))
}
func realPrice(price int) func(discount int) int{
return func(discount int) int {
return price * discount
}
}
~~~
## 递归函数