golang_函数初窥
知識點:
1. 完整形式`func (接收者)函數名(參數 參數類型...) 返回值類型 { 函數體 }`其中:
a. `func`: 關鍵字,表明後面聲明的是一個變量,
b. `接收者`: 作用於什麼結構體(這一部分內容在結構體部分講解),當有接收者的時候函數也叫方法
c. `函數名`: 函數的名字,用於調用函數使用
d. `參數列表`: 需要傳遞的參數,
e. `返回值`: 函數執行結束之後返回的內容
f. `函數體`: 函數要實現的功能
2. 注意:
a. 函數名必須遵循標識符命名規範
b. 同一個包中的函數不能同名--與C#或java不同的是golang沒有重載
c. 多個參數之間使用逗號間隔
d. 多個相同類型的參數可以簡寫為`func f(a, b int)`的形式.
e. 當返回值帶有名字的時候return語句可以只寫return
f. 函數的參數傳遞為值傳遞,需要改變實參內容需要進行地址傳遞
可變參數
當函數的參數個數不確定的時候可以使用這這樣寫,但是要注意,可變參數一定是參數列表的最後一個參數.
func sum(x ...int) (sum int) {
for _, v := range x {
sum += v
}
return
}
func main() {
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個)
函數變量
函數變量就是把函數當做一種類型的變量,例如:type fufunc(int, int) int
表示定義一個叫做fu的函數類型,這個函數類型能夠接受兩個int類型的參數,並且返回一個int類型的參數.
比如:
func sum(x, y int) int {
return x + y
}
func sub(x, y int) int {
return x - y
}
func main() {
type fu func(int, int) int
var f1 fu
f1 = sum
fmt.Println(f1(1, 2))
f1 = sub
fmt.Println(f1(10, 4))
}
這裡你需要注意的是,fu才是類型,而f1是變量.而函數變量說明函數是可以當做一種類型的,也就暗示你函數可以當做參數傳遞,比如下面的例子:
func calc(x, y int, f func(int, int) int) int {
return f(x, y)
}
func main() {
fmt.Println(calc(1, 2, sum))
fmt.Println(calc(1, 2, sub))
}
在上面的代碼中,參數f就表示一個函數類型的變量,相當於在上一個例子中的fu類型.不過函數既然能作為參數傳遞,那麼能否作為返回值傳遞呢?答案是肯定的,不信你看:
func f(i int) func(int, int) int {
if 1 == i {
return sum
} else {
return sub
}
}
func main() {
fmt.Println(f(1)(1, 2))
}
在f函數中就通過輸入的數字來確定調用sum函數還是sub函數.
匿名函數
匿名就是不知道名字的意思,匿名函數就是沒有定義名字的函數--可以類比於其他編程語言種的lambda表達式學習
其定義的格式是func (參數列表) (返回值列表) {函數體}
是不是簡單明了?
下面舉個栗子:
c := func(x, y int) int {
return x - y
}
fmt.Println(c(1, 2))
b := func(x, y int) int {
return x + y
}
fmt.Println(b(1, 2))
像這種簡單的事情就可以使用匿名函數完成,就不用定義在全局了.而後面都只需要使用c, b這兩個變量就能調用著兩個匿名函數,實現裡面的功能.
如果我希望這個函數在定義完成之後立即執行怎麼辦呢?只需要在最後添加一個小括號傳入參數即可.
c := func(x, y int) int {
return x - y
}(1, 2)
fmt.Println(c)
b := func(x, y int) int {
return x + y
}(1, 2)
fmt.Println(b)
注意,由於函數在定義完成之後便立即執行了,所以會返回函數的返回值,也就是說,後面已經不能使用c,b調用這兩個匿名函數了--當你需要這個匿名函數只執行一次,之後不再執行的時候即可如此編寫.
到這裡你可能發現了一個問題:函數可以沒有參數,沒有返回值,沒有沒有函數名,甚至沒有函數體,但是唯一不能沒有的是關鍵字func
.