一、函數
函數的參數
1.1 參數的使用
形式參數:定義函數時,用於接收外部傳入的數據,叫做形式參數,簡稱形參。
實際參數:調用函數時,傳給形參的實際的數據,叫做實際參數,簡稱實參。
函數調用:
A:函數名稱必須匹配
B:實參與形參必須一一對應:順序,個數,類型
1.2 可變參
Go函數支持變參。接受變參的函數是有着不定數量的參數的。為了做到這點,首先需要定義函數使其接受變參:
func myfunc(arg ...int) {}
arg ...int
告訴Go這個函數接受不定數量的參數。注意,這些參數的類型全部是int。在函數體中,變量arg是一個int的slice:
for _, n := range arg {
fmt.Printf("And the number is: %d\n", n)
}
1.3 參數傳遞
go語言函數的參數也是存在值傳遞和引用傳遞
函數運用場景
值傳遞
package main
import (
"fmt"
"math"
)
func main(){
/* 聲明函數變量 */
getSquareRoot := func(x float64) float64 {
return math.Sqrt(x)
}
/* 使用函數 */
fmt.Println(getSquareRoot(9))
}
引用傳遞
這就牽扯到了所謂的指針。我們知道,變量在內存中是存放於一定地址上的,修改變量實際是修改變量地址處的內
存。只有add1函數知道x變量所在的地址,才能修改x變量的值。所以我們需要將x所在地址&x傳入函數,並將函數的參數的類型由int改為*int,即改為指針類型,才能在函數中修改x變量的值。此時參數仍然是按copy傳遞的,只是copy的是一個指針。請看下面的例子
package main
import "fmt"
//簡單的一個函數,實現了參數+1的操作
func add1(a *int) int { // 請注意,
*a = *a+1 // 修改了a的值
return *a // 返回新值
} f
unc main() {
x := 3
fmt.Println("x = ", x) // 應該輸出 "x = 3"
x1 := add1(&x) // 調用 add1(&x) 傳x的地址
fmt.Println("x+1 = ", x1) // 應該輸出 "x+1 = 4"
fmt.Println("x = ", x) // 應該輸出 "x = 4"
}
- 傳指針使得多個函數能操作同一個對象。
- 傳指針比較輕量級 (8bytes),只是傳內存地址,我們可以用指針傳遞體積大的結構體。如果用參數值傳遞的話, 在每次copy上面就會花費相對較多的系統開銷(內存和時間)。所以當你要傳遞大的結構體的時候,用指針是一個明智的選擇。
- Go語言中slice,map這三種類型的實現機制類似指針,所以可以直接傳遞,而不用取地址后傳遞指針。(注:若函數需改變slice的長度,則仍需要取地址傳遞指針)