匿名函式

匿名函式

匿名:臨時建立一個函式只需要用一次時

 // 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 

延伸

URLNote

Map/Reduce/Filter只是一种控制逻辑,真正的业务逻辑是在传给他们的数据和那个函数来定义的。是的,这是一个很经典的“业务逻辑”和“控制逻辑”分离解耦的编程模式

Rob Pike https://github.com/robpike/filter

有大量的程序员都在问Go语言官方什么时候在标准库中支持 Map/Reduce,Rob Pike说,这种东西难写吗?还要我们官方来帮你们写么?这种代码我多少年前就写过了,但是,我从来一次都没有用过,我还是喜欢用“For循环”,我觉得你最好也跟我一起用 “For循环”。

“函數式編程是一種編程範式,它將計算視為數學函數的評估,並避免狀態和可變數據”

Last updated