Go語言學習——匿名函式、閉包
阿新 • • 發佈:2022-05-14
匿名函式
匿名函式的定義格式:
func(引數)(返回值){
函式體
}
沒有名字的函式
package main import "fmt" // 匿名函式 // var f1 = func (x, y int) { // fmt.Println(x + y) // } func main(){ // f1(10, 20) // 函式內部沒有辦法宣告帶名字的函式 // 匿名函式 f1 := func (x, y int) { fmt.Println(x + y) } f1(10, 20) // 如果只是呼叫一次的函式,還可以簡寫成立即執行函式 func (x, y int) { fmt.Println(x + y) fmt.Println("Hello world") } (10, 20) }
閉包
閉包=函式+引用環境
package main import "fmt" // 閉包 func f1(f func()) { fmt.Println("this is f1") f() } func f2(x, y int) { fmt.Println("this is f2") fmt.Println(x + y) } // 定義一個函式對f2進行包裝 func f3() func() { tmp := func () { fmt.Println("Hello") } return tmp } func test(x int) { tmp := func () { fmt.Println(x) // 先在自己這裡面找 } tmp() } func test2(x func (int, int), m, n int) { tmp := func () { x (m, n) } tmp() // x(m, n) } func test3(x func(int, int), m, n int) { x (m, n) } func test4(x func (int, int), m, n int) func() { tmp := func () { x (m, n) } return tmp } func main(){ test(100) test2(f2, 100, 200) test3(f2, 100, 200) ret := test4(f2, 100, 200) ret() }
一個函式除了用到它內部定義的語句之外還可以引用它外部的變數
package main import "fmt" // 閉包 func f1(f func()) { fmt.Println("this is f1") f() } func f2(x, y int) { fmt.Println("this is f2") fmt.Println(x + y) } // 要求: // f1(f2) func f3(f func(int, int), x, y int) func() { tmp := func () { // fmt.Println(x + y) // f2() f(x, y) } return tmp } // 定義一個函式對f2進行包裝 // func f3() func() { // tmp := func () { // fmt.Println("Hello") // } // return tmp // } // func test(x int) { // tmp := func () { // fmt.Println(x) // 先在自己這裡面找 // } // tmp() // } // func test2(x func (int, int), m, n int) { // tmp := func () { // x (m, n) // } // tmp() // x(m, n) // } // func test3(x func(int, int), m, n int) { // x (m, n) // } // func test4(x func (int, int), m, n int) func() { // tmp := func () { // x (m, n) // } // return tmp // } func main(){ // test(100) // test2(f2, 100, 200) // test3(f2, 100, 200) // ret := test4(f2, 100, 200) // ret() ret := f3(f2, 100, 200) // 把原來需要傳遞兩個int 型別的引數包裝成一個不需要傳參的函式 fmt.Printf("%T\n", ret) f1(ret) }
閉包 = 函式 + 外部變數的引用
package main
import "fmt"
// 閉包是什麼
// 閉包是一個函式,這個函式包含了它外部作用域的一個變數
// 底層的原理:
// 1. 函式可以作為返回值
// 2. 函式內部查詢變數的順序,先在自己內部找,找不到往外層找
func adder(x int) func(int) int {
// var x int
// var x = 100
return func(y int) int {
x += y
return x
}
}
func main() {
// ret := adder()
ret := adder(100)
ret2 := ret(200)
fmt.Println(ret2)
// var f = adder()
// fmt.Println(f(10)) //10
// fmt.Println(f(20)) //30
// fmt.Println(f(30)) //60
// f1 := adder()
// fmt.Println(f1(40)) //40
// fmt.Println(f1(50)) //90
}
閉包例子
package main
import (
"fmt"
"strings"
)
// 閉包
func makeSuffixFunc(suffix string) func(string) string {
return func(name string) string {
if !strings.HasSuffix(name, suffix) {
return name + suffix
}
return name
}
}
func main() {
jpgFunc := makeSuffixFunc(".jpg")
txtFunc := makeSuffixFunc(".txt")
fmt.Println(jpgFunc("test")) //test.jpg
fmt.Println(jpgFunc("test1.jpg")) //test1.jpg
fmt.Println(txtFunc("test")) //test.txt
fmt.Println(txtFunc("test2.txt")) //test2.txt
}package main
import (
"fmt"
"strings"
)
// 閉包
func makeSuffixFunc(suffix string) func(string) string {
return func(name string) string {
if !strings.HasSuffix(name, suffix) {
return name + suffix
}
return name
}
}
func main() {
jpgFunc := makeSuffixFunc(".jpg")
txtFunc := makeSuffixFunc(".txt")
fmt.Println(jpgFunc("test")) //test.jpg
fmt.Println(jpgFunc("test1.jpg")) //test1.jpg
fmt.Println(txtFunc("test")) //test.txt
fmt.Println(txtFunc("test2.txt")) //test2.txt
}
閉包=函式+引用環境
package main
import "fmt"
// 關鍵字 函式名(引數)(返回值){}
func calc(base int) (func(int) int, func(int) int) {
add := func(i int) int {
base += i
return base
}
sub := func(i int) int {
base -= i
return base
}
return add, sub
}
func main() {
f1, f2 := calc(10)
// 修改的是同一個base
fmt.Println(f1(1), f2(2)) //11 9
fmt.Println(f1(3), f2(4)) //12 8
fmt.Println(f1(5), f2(6)) //13 7
}