函數(shù)不但可以用于封裝數(shù)據(jù)、分割功能、解耦邏輯,還可以化身為普通的值,在其他函數(shù)間傳遞、賦予變量、做類型判斷和轉(zhuǎn)換等。
函數(shù)值可以成為被隨意傳播的獨(dú)立邏輯組件(功能模塊)。
函數(shù)定義
函數(shù)的基本組成為:關(guān)鍵字func、函數(shù)名、參數(shù)列表、返回值列表、函數(shù)體、返回語句
func function_name( [parameter list] ) [return_types] {
函數(shù)體
}
func Add(a,b int) (res int, err error){
if a < 0 || b < 0 {
err = errors.New("數(shù)值不能小于0")
return
}
res = a+b
return
}
不管傳遞的是指針、引用還是其它類型參數(shù),都是值拷貝傳遞的,區(qū)別在于拷貝的目標(biāo)是目標(biāo)對(duì)象還是拷貝指針而已。
在函數(shù)調(diào)用之前,編譯器會(huì)為形參和返回值分配內(nèi)存空間,并將實(shí)參拷貝到形參內(nèi)存。
函數(shù)的簽名
參數(shù)
參數(shù)列表中,若相鄰變量類型一致可以合寫。
如下面例子,二者等價(jià)
func Add(a int, b int) int {}
func Add(a,b int) int {}
不定參數(shù)
不定參數(shù)是指函數(shù)傳入的參數(shù)個(gè)數(shù)為不定數(shù)量。且必須是最后一個(gè)參數(shù)。
args ...type
的形式來表示不定參數(shù),它是一個(gè)語法糖,即這種語法對(duì)語言的功能沒有影響,但方便程序員使用。
下例展示了類型為int的不定參數(shù)的使用
func myfunc(args ...int) {
for _, arg := range args {
fmt.Println(arg)
}
}
//myfunc(1,2,5,7) 調(diào)用
//myfunc(3,4,7,2,4,6) 調(diào)用
如果想傳遞任意類型的參數(shù),可以使用 args ...interface{}
如Go語言標(biāo)準(zhǔn)庫(kù)中fmt.Printf()的函數(shù)原型
func Printf(format string, args ...interface{}) {}
返回值
返回值列表中,如果只有一個(gè)返回值,返回值類型可以不加括號(hào),如
func Add(a,b int) int {}
多返回值
Go語言的函數(shù)或者成員方法可以有多個(gè)返回值!其他語言只能有一個(gè)返回值
返回值列表中,如果有多個(gè)返回值,return語句必須符合返回值列表類型的順序
func Add(a,b int, c string) (int, string) {
x := a+b //int類型
y := c//string類型
return x,y //x y的順序要對(duì),反過來就會(huì)報(bào)錯(cuò)
}
返回值列表中,除了寫返回值的類型外,也可以直接指明返回值名稱,這樣就不用在函數(shù)體里聲明返回值的名稱了(直接用返回值列表中聲明的名稱),而且return句也可以省略return的內(nèi)容(自動(dòng)匹配返回值列表中的內(nèi)容)。這時(shí),即使只有一個(gè)返回值也要加括號(hào)
func Add(a,b int) (res int, err error) {
res = a+b //不用先聲明res了,返回值列表中聲明過了
return //等價(jià)于return res,err
}
上面寫法也可以用下面的替代
func Add(a,b int) (res int, err error) {
return a+b,err
}
跳過返回值
如果調(diào)用了一個(gè)多返回值的函數(shù)或方法,但不想關(guān)心其中的某個(gè)返回值,可以用一個(gè)下劃線_
來跳過該返回值。
如調(diào)用者在讀文件時(shí)不想關(guān)心Read()函數(shù)返回的錯(cuò)誤碼
n, _ := f.Read(buf)
函數(shù)的調(diào)用
函數(shù)調(diào)用很簡(jiǎn)單,只要在函數(shù)名后加小括號(hào)即可。
Add(1,2)
匿名函數(shù)只要在函數(shù)后面加小括號(hào)即可自調(diào)用
func (a,b int) int {
return a+b
}(1,2)
匿名函數(shù)與閉包
匿名函數(shù)
匿名函數(shù)顧名思義,就是沒有函數(shù)名的函數(shù)。
func (a,b int) int {
return a+b
}
匿名函數(shù)可以直接賦值給一個(gè)變量
f := func (a,b int) int {
return a+b
}
或者自調(diào)用
func (a,b int) int {
return a+b
}(1,2)
閉包
引用了自由變量的匿名函數(shù)就是一個(gè)閉包函數(shù)。
閉包體現(xiàn)的是由不確定到確定的一個(gè)過程。它的內(nèi)部邏輯并不是完整的,由一部分邏輯需要這個(gè)自由變量參與完成。
閉包函數(shù)的意義:由于自由變量只由當(dāng)被調(diào)用的時(shí)候才確定,所以,閉包函數(shù)的部分邏輯是動(dòng)態(tài)生成的,可以借此才程序運(yùn)行的過程中,根據(jù)需要生成功能不同的函數(shù),繼而影響后續(xù)程序的行為。