本文首發於公眾號:Hunter後端
原文鏈接:Golang基礎筆記八之函數
本篇筆記介紹 Golang 裏函數相關的內容,以下是本篇筆記目錄:
- 函數的定義語法
- 函數返回值
- 可變參數函數
- 匿名函數
- 閉包
1、函數的定義語法
函數的定義格式如下:
func 函數名(參數列表) (返回值列表) { 函數體 }
比如下面是一個兩數相加返回其和的函數:
func add(a, b int) int {
return a + b
}
調用的話,直接傳參調用即可:
sum := add(1, 4)
fmt.Println(sum)
傳入的參數可以傳值,也可以傳指針,如果傳指針的話,在函數內部修改後,會影響原值。
以下是一個傳指針修改的示例:
func test(a *int, b int) {
*a += 2
b += 2
}
func main() {
a := 1
b := 1
fmt.Printf("調用前 a:%d, b:%d\n", a, b)
test(&a, b)
fmt.Printf("調用後 a:%d, b:%d\n", a, b)
}
輸出結果為:
調用前 a:1, b:1
調用後 a:3, b:1
2、函數返回值
函數返回值可以返回單個或多個,在函數定義的時候指定返回類型即可:
func add(a, b int) int {
return a + b
}
func swap(a, b int) (int, int) {
return b, a
}
還可以對返回值命名,就是在定義函數的時候,將返回值提前聲明定義,然後在函數內部對其賦值,函數末尾可以省去 return 具體變量的操作。
比如下面:
func calc(a, b int) (sum, sub int) {
sum = a + b
sub = a - b
return
}
3、可變參數函數
可變參數函數可以接受任意數量的參數,在函數定義的時候,類型前面加上 ... 即表示該參數是可變參數,而在函數內部,可將其作為切片使用。
下面是一個示例,可以接受任意多個元素,作為求和函數的參數:
func sum(nums ...int) int {
total := 0
for _, num := range nums {
total += num
}
return total
}
調用的時候,可以直接傳入任意數量參數:
sum(1, 2, 3, 4)
也可以傳入一個切片:
slice := []int{1, 2, 3}
s2 := sum(slice...)
4、匿名函數
匿名函數通常用於臨時需要處理某個功能,或需要將其作為參數傳遞給其他變量的場景。
比如下面定義並立即調用了匿名函數:
total := func(a, b int) int {
return a + b
}(2, 4)
也可以將其賦值給某個變量,再由該變量來調用:
sumFunc := func(a, b int) int {
return a + b
}
sumFunc(1, 2)
5、閉包
閉包是指能夠讀取其他函數內部變量的函數,即使該函數已經執行完畢,其作用域內的變量也不會被銷燬。
我們可以使用閉包來捕獲外部函數的局部變量,並將其生命週期延長至閉包本身,比如實現一個計數器:
func counter() func() int {
count := 0
return func() int {
count += 1
return count
}
}
counterFunc := counter()
fmt.Println(counterFunc())
fmt.Println(counterFunc())
fmt.Println(counterFunc())
fmt.Println(counterFunc())
也可以根據外部傳入的參數生成不同的閉包實例,比如實現一個計算器:
func calculate(calculate_type string) func(a, b int) int {
if calculate_type == "add" {
return func(a, b int) int {
return a + b
}
} else if calculate_type == "sub" {
return func(a, b int) int {
return a - b
}
} else {
return func(a, b int) int { return a + b }
}
}
addFunc := calculate("add")
fmt.Println(addFunc(10, 5))
subFunc := calculate("sub")
fmt.Println(subFunc(3, 1))
而閉包也可以維護迭代的狀態,因此可以實現迭代器的功能,比如實現一個斐波那契數列生成器:
func fibonacci() func() int {
a, b := 0, 1
return func() int {
f_count := a
a, b = b, a+b
return f_count
}
}
f := fibonacci()
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())