# 函數
所有函數都是全局函數,可以被項目中其他文件使用,在項目中函數名唯一。
全局變量作用域是項目中所有文件
全局變量和 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
}
}
~~~
## 遞歸函數