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的記憶體位址。