匿名函式
匿名函式
匿名:臨時建立一個函式只需要用一次時
// Anonymous function
func(){
fmt.Println("Welcome!")
}()
匿名函數經常被用於實現回調函數、閉包等。
使用匿名函數會使得數據和行爲具有較好抽象能力,使得程式可複用有質量的提升
回調CallBack: 即函數可以作爲另一個函數的返回值或參數
閉包:將變數本身關閉在自己的範疇中
var addr = func() func() {
var i int
return func() {
//返回閉包時並不是單純返回一個函數,而是返回了一個結構體,記錄下函數返回地址和引用的環境中的變量地址。
i++
fmt.Printf("var (%p) = %d\n", &i, i)
//變數位址值都是相同的,閉包將變數本身關閉在自己的範疇中,而不是變數的值
}
}()
addr() //1
addr() //2 注意這邊不會是1,而是遞增
addr() //3
for-loop 執行goroutine
最常遇到閉包的坑與解法
func main() {
for i := 1; i <= 5; i++ {
func() {
fmt.Println("i", i)
}()
}
for num := 1; num <= 5; num++ { //使用闭包,当 for-loop 执行完之后 goroutine 才开始执行,值都指向最後一個
go func() {
fmt.Println("num", num)
}()
}
for val := 1; val <= 5; val++ { //解决方法 将 i 作为一个参数传入 goroutine 中
go func(val int) {
fmt.Println("val", val)
}(val)
}
time.Sleep(5 * time.Second)
}
費氏陣列(閉包版)
>一般版用遞迴函式算的演算法是屬於 O(n^2)
>閉包版 當計算一次要執行一次,執行n次時執行n次,O(n)需要有遞增特性
package main
import "fmt"
func fibonacci() func() int {
a, b := 0, 1
fmt.Println("start with:", a, b)
return func() int {
a, b = b, a+b
return a
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Print(f(), " ")
}
}
start with: 0 1
1 1 2 3 5 8 13 21 34 55
延伸
URL
Note
Map/Reduce/Filter只是一种控制逻辑,真正的业务逻辑是在传给他们的数据和那个函数来定义的。是的,这是一个很经典的“业务逻辑”和“控制逻辑”分离解耦的编程模式
Rob Pike https://github.com/robpike/filter
有大量的程序员都在问Go语言官方什么时候在标准库中支持 Map/Reduce,Rob Pike说,这种东西难写吗?还要我们官方来帮你们写么?这种代码我多少年前就写过了,但是,我从来一次都没有用过,我还是喜欢用“For循环”,我觉得你最好也跟我一起用 “For循环”。
“函數式編程是一種編程範式,它將計算視為數學函數的評估,並避免狀態和可變數據”
Last updated