golang_函式初窺
知識點:
1. 完整形式`func(接收者)函式名(引數引數型別...)返回值型別{函式體}`其中: a. `func`: 關鍵字,表明後面宣告的是一個變數, b. `接收者`: 作用於什麼結構體(這一部分內容在結構體部分講解),當有接收者的時候函式也叫方法 c. `函式名`: 函式的名字,用於呼叫函式使用 d. `引數列表`: 需要傳遞的引數, e. `返回值`: 函式執行結束之後返回的內容 f. `函式體`: 函式要實現的功能 2. 注意: a. 函式名必須遵循識別符號命名規範 b. 同一個包中的函式不能同名--與C#或java不同的是golang沒有過載 c. 多個引數之間使用逗號間隔 d. 多個相同型別的引數可以簡寫為`funcf(a,bint)`的形式. e. 當返回值帶有名字的時候return語句可以只寫return f. 函式的引數傳遞為值傳遞,需要改變實參內容需要進行地址傳遞
可變引數
當函式的引數個數不確定的時候可以使用這這樣寫,但是要注意,可變引數一定是引數列表的最後一個引數.
funcsum(x...int)(sumint){
for_,v:=rangex{
sum+=v
}
return
}
funcmain(){
sum1:=sum(1,2,3,4)
fmt.Println(sum1)
sum2:=sum(100)
fmt.Println(sum2)
}
解釋:
1. 函式返回值不僅為int型別,同時返回的變數為sum
2. 因為在返回值的地方sum已經定義,所以在函式體內部需要二次定義
3. 因為函式返回值為有名字的,所以return只需要寫return就可以了,但是要加上sum也是可以的
4. 因為引數列表是可變引數,所以可以傳遞任意多個引數(包括0個)
函式變數
函式變數就是把函式當做一種型別的變數,例如:typefufunc(int,int)int
表示定義一個叫做fu的函式型別,這個函式型別能夠接受兩個int型別的引數,並且返回一個int型別的引數.
比如:
funcsum(x,yint)int{
returnx+y
}
funcsub(x,yint)int{
returnx-y
}
funcmain(){
typefufunc(int,int)int
varf1fu
f1=sum
fmt.Println(f1(1,2))
f1=sub
fmt.Println(f1(10,4))
}
這裡你需要注意的是,fu才是型別,而f1是變數.而函式變數說明函式是可以當做一種型別的,也就暗示你函式可以當做引數傳遞,比如下面的例子:
funccalc(x,yint,ffunc(int,int)int)int{
returnf(x,y)
}
funcmain(){
fmt.Println(calc(1,2,sum))
fmt.Println(calc(1,2,sub))
}
在上面的程式碼中,引數f就表示一個函式型別的變數,相當於在上一個例子中的fu型別.不過函式既然能作為引數傳遞,那麼能否作為返回值傳遞呢?答案是肯定的,不信你看:
funcf(iint)func(int,int)int{
if1==i{
returnsum
}else{
returnsub
}
}
funcmain(){
fmt.Println(f(1)(1,2))
}
在f函式中就通過輸入的數字來確定呼叫sum函式還是sub函式.
匿名函式
匿名就是不知道名字的意思,匿名函式就是沒有定義名字的函式--可以類比於其他程式語言種的lambda表示式學習
其定義的格式是func(引數列表)(返回值列表){函式體}
是不是簡單明瞭?
下面舉個栗子:
c:=func(x,yint)int{
returnx-y
}
fmt.Println(c(1,2))
b:=func(x,yint)int{
returnx+y
}
fmt.Println(b(1,2))
像這種簡單的事情就可以使用匿名函式完成,就不用定義在全域性了.而後面都只需要使用c, b這兩個變數就能呼叫著兩個匿名函式,實現裡面的功能.
如果我希望這個函式在定義完成之後立即執行怎麼辦呢?只需要在最後新增一個小括號傳入引數即可.
c:=func(x,yint)int{
returnx-y
}(1,2)
fmt.Println(c)
b:=func(x,yint)int{
returnx+y
}(1,2)
fmt.Println(b)
注意,由於函式在定義完成之後便立即執行了,所以會返回函式的返回值,也就是說,後面已經不能使用c,b呼叫這兩個匿名函式了--當你需要這個匿名函式只執行一次,之後不再執行的時候即可如此編寫.
到這裡你可能發現了一個問題:函式可以沒有引數,沒有返回值,沒有沒有函式名,甚至沒有函式體,但是唯一不能沒有的是關鍵字func
.