這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
1、簽名:
go語言中,函數的簽名就是函數的參數類型及傳回值類型,是這個函數呈現給使用環境的介面,與名字無關。
2、函數變數和函數賦值
go語言支援函數類型的變數和賦值。
相同簽名的函數是同一類型的,同一類型的函數才可以相互賦值。
函數變數也是支援強制轉換的,不過這裡必須是同一類型的函數,才能進行轉換。
例:
(1)、強制轉換:
packagemain
import"fmt"
typef_typefunc(x,yint)(int)
varff=f_type(func(x,yint)(int){
fmt.Println("funcff")
returnx+y
})
funcmain(){
ff(2,4)
}
上面代碼,首先定義f_type的函數類型,該類型的函數必須有2個int的入參,一個int的出參。然後定義一個兩個int入參,一個int出參的匿名函數,並強轉成f_type類型賦值給ff。
(2)、賦值
packagemain
import"fmt"
varpr=fmt.Println
varf=func(i,jint)int{
pr("funcf:")
pr("i+j=",i+j)
returni+j
}
funcmain(){
pr("tmppr=fmt.Println,anduse\"pr\"toprintinfo")
f(1,3)
}
運行結果如下:
F:/go-code/tmp-func/tmp-func.exe[F:/go-code/tmp-func]
tmp pr = fmt.Println, anduse "pr" to print info
func f:
i + j = 4
成功: 進程結束代碼 0.
3、閉包
下面內容摘自《Go語言 雲動力》,4.5-閉包。
和變數的聲明不同,Go語言不能在函數裡聲明另外一個函數。所以在Go的源檔案裡,函式宣告都是出現在最外層的。
“聲明”就是把一種類型的變數和一個名字聯絡起來。
Go裡有函數類型的變數,這樣,雖然不能在一個函數裡直接聲明另一個函數,但是可以在一個函數中聲明一個函數類型的變數,此時的函數稱為閉包(closure)。
例:
packagemain
import"fmt"
funcmain(){
add:=func(baseint)func(int)(int){
returnfunc(iint)(int){
returnbase+i
}
}
add5:=add(5)
fmt.Println("add5(10)=",add5(10))
}
這個例子唯一的使用價值大概就是用來展示閉包的構建和使用。
add是一個閉包,因為它是無名的函數類型的變數。可以認為它是一個閉包作坊,根據入參返回(生產)一個閉包。這樣add5就是使用5作為add的參數得到的一個閉包。
閉包的聲明是在另一個函數的內部,形成嵌套。和塊的嵌套一樣,內層的變數可以遮蓋同名的外層的變數,而且外層變數可以直接在內層使用。如add的base參數在return返回的閉包的外層,所以它的值5在add返回並賦值給add5後依舊存在。當add5執行時,參數i可以從這個外層得到的base相加,得到結果15.
如果聯想到函數調用,會奇怪add函數return之後的架構已經不存在了,為什麼base還可以用呢?答案是go的編譯器會把閉包使用的外圍變數分配到堆上,而堆上的變數,是不會隨函數返回自動消失的,它們在用完之後,才會被記憶體回收。