【go語言學習筆記】閉包和匿名函數

1.匿名函數和閉包的概念

匿名函數: 聲明函數時不顯式聲明函數名。
閉包: 簡單來說就是一個函數定義中引用了函數外定義的變量,並且該函數可以在其定義環境外被執行。這樣的一個函數我們稱之爲閉包。實際上閉包可以看做一種更加廣義的函數概念。因爲其已經不再是傳統意義上定義的函數。

go語言中的匿名函數聲明方法類似於js,而閉包聲明類似於python。

demo:

package main

import "fmt"

func main() {
	a := 10
	str := "golang"

	//匿名函數,沒有函數名字
	//可以捕獲同一個作用域的變量
	f1 := func() {
		fmt.Println(a, str)
	}
	f1()

	//給一個函數類型起別名
	type FuncType func() //函數沒有參數,沒有返回值

	// 聲明變量
	var f2 FuncType
	f2 = f1
	f2()

	// 定義匿名函數的同時調用
	func() {
		fmt.Println(a, str)
	}() // 後面的()代表調用此匿名函數

	// 帶參數的匿名函數
	func(i, j int) {
		fmt.Println(i + j)
	}(5, 6)

	// 匿名函數有參有返回值
	var b = func(i, j int) int {
		return i + j
	}(5, 7)
	fmt.Println(b)

	func() {
		//閉包以引用的方式捕獲外部變量,裏面改了外面的變量也會被改變
		a = 66
		str = "abc"
		fmt.Println("內部:", a, str)
	}()
	fmt.Println("外部: ", a, str)
}
	

2.閉包的特點

  • 閉包不關心這些捕獲了的變量和常量是否已經超出了作用域,只要閉包還在使用這些變量,那麼這些變量就不會被垃圾回收
  • 我們看到的變量的生命週期不由它的作用域決定,當f返回後,變量x仍然隱式的存在於f中。
package main

import "fmt"

// 返回一個匿名函數
func test() func() int {
	var x int
	return func() int { //閉包
		x++
		return x * x
	}
}

//閉包不關心這些捕獲了的變量和常量是否已經超出了作用域,只要閉包還在使用這些變量,那麼這些變量就不會被垃圾回收
//我們看到的變量的生命週期不由它的作用域決定,當f返回後,變量x仍然隱式的存在於f中。

func main() {
	var f = test()
	fmt.Println(f())
	fmt.Println(f())
	fmt.Println(f())
	fmt.Println(f())
	fmt.Println(f())
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章