在go語言中,函數的基本組成爲:關鍵字func、函數名、參數列表、返回值、函數體和返回語句數組
定義一個最簡單的加法函數閉包
func Add(a int,b int)(ret int,err error){ if a < 0 || b < 0{ err = errors.New("這個函數只支持兩個非負數的數字相加") return } return a + b,nil }
若是參數列表中若干相鄰的參數類型是相同的話,好比上述例子中的a和b,則能夠在參數列表中省略前面的類型聲明,例如:函數
func Add(a,b int)(ret int,err error){ // ... }
若是返回值列表中多個返回值的類型相同,也能夠用一樣的方式合併code
若是函數只有一個返回值,也能夠這樣寫:對象
func Add(a,b int) int{ // ... }
函數調用很是方便,只須要事先導入了該函數所在的包,就能夠直接調用了,在go語言中,對函數命名有必定要求,只有大寫開頭的字母才能夠被其餘包調用,小寫字母開頭的函數只能在本包被調用作用域
例:假設Add函數在func1中開發
package main import ( "fmt" //導入包 "functions/func1" ) func main() { a := 1 b := 2 // 經過包名調用函數 ret,err := func1.Add(a,b) fmt.Println(ret,err) }
不定參數是值函數傳入的參數個數爲不定數量。io
func main(){ // myfunc函數能夠接收任意個int類型的參數 myfunc(1,2,3,4,5,6,7,8) } // ... 表示不定參數 func myfunc(args ...int){ for _,arg := range args { fmt.Println(arg) } }
...type格式的類型只能做爲函數的參數類型存在,而且必須是最後一個參數。。它是一
個語法糖(syntactic sugar),即這種語法對語言的功能並無影響for循環
從內部實現機理上來講,類型...type本質上是一個數組切片,也就是[]type,這也是爲
什麼上面的參數args能夠用for循環來得到每一個傳入的參數。
假如沒有...type這樣的語法糖,開發者將不得不這麼寫:function
func myfunc2(args []int) { for _, arg := range args { fmt.Println(arg) } }
從函數的實現角度來看,這沒有任何影響,該怎麼寫就怎麼寫。但從調用方來講,情形則完
全不一樣:
myfunc2([]int{1, 3, 7, 13})
func myfunc(args ...interface{}){ // ... }
用interface{}傳遞任意類型數據是go語言的慣例用法
匿名函數由一個不帶函數名的函數聲明和函數體組成,如:
func(a,b int) bool { return a * b }
匿名函數能夠直接賦值給一個變量或者直接執行
// 賦值給一個變量 f := func(a,b int) int { return a * b } // 直接執行 func(a,b int) bool { return a * b }(1,2)
func main() { var j int = 5 //一個函數的返回值是一個函數的執行 a := func()(func()) { var i int = 10 return func() { fmt.Printf("i,j : %d %d \n",i,j) } }() a() j *= 2 a() }