天天看點

Go語言基礎篇--7.Go語言之【回調函數+閉包】1.回調函數2.閉包

1.回調函數

函數的類型定義:

定義兩個函數func1()和func2(),如果講func1函數作為func2函數的參數傳給func2,那麼此時func2函數可算作是高階函數,func1函數則為回調函數。示例:

func main() {
	res := operate(1, 5, add)//這裡要注意,要寫add而不是add(),add()表示的是函數的執行結果
	fmt.Println(res)
}

func add(a, b int) int {
	return a + b
}
func operate(a, b int, funcName func(int, int) int) int {
	fmt.Println(a, b, funcName)
	res := funcName(a, b)
	return res
}
/*分析:
func operate(a, b int, funcName func(int, int) int) int
對于operate函數,先傳入兩個整形資料,接着傳入一個函數,
這個函數類型是func(int, int) int,表示輸入兩個int資料,
傳回一個int資料,operate括号外面的int表示operate函數
最終傳回一個int類型資料
*/
           

2.閉包

概念:在一個外層函數當中有内層函數,并且在内層函數中會操作外層函數中的局部變量(自定義或傳入的參數),并且外層函數會把内層函數作為傳回值。此時,内層函數和該局部變量的結構統稱為閉包結構。

func main() {
	close := closureTest()
	fmt.Printf("%T\n", close)
	fmt.Println(close())
	fmt.Println(close())
	fmt.Println(close())
}
/*分析:
close被定義為一個函數,其類型與closureTest函數的傳回值類型相同,實際上就是内層函數。
運作該行代碼時close := closureTest(),i被初始化為0;接下來每執行一次close()那麼i的值就會加1
這是因為一個内層函數對外層函數的局部變量進行操作,
且外層函數會把内層函數作為傳回值,
此時該局部變量的生命周期會發生改變,
不會随着外層函數的結束而結束,
因為内層函數還要繼續使用
*/
func closureTest() func() int { //外層函數
	//局部變量
	i := 0
	fun := func() int { //内層函數
		i++
		return i
	}
	return fun //傳回該内層函數(實際上是個匿名函數)
}
/*result*/
//func() int
//1
//2
//3

           
func main() {
	close := closureTest()
	fmt.Printf("%T\n", close)
	fmt.Println(close())
	fmt.Println(close())
	fmt.Println(close())
	fmt.Println(close())
	
	close0 := closureTest()
	fmt.Println(close0())
	fmt.Println(close0())
	fmt.Println(close())
}
/*result*/
//1
//2
//3
//4
//1
//2
//5
           

再次将close定義為closureTest函數,此時會重新開辟一塊i的記憶體空間,此時close0()通路的是新的i的記憶體位址,而後續調用的close()還會繼續通路之前的舊的i的記憶體位址。

繼續閱讀