函數是基本的代碼塊,用于執行一個任務。Go 語言最少有 1 個?main()
?函數。你可以通過函數來劃分不同功能,邏輯上每個函數執行的是指定的任務。
函數聲明告訴了編譯器函數的名稱、返回類型和參數。
函數三要素
- 名稱 ==》功能
- 參數 ==》接口
- 返回值 ==》結果
函數分類
- 內置函數 ==》不需要引用其他模塊,直接使用,例如:
len()
- 標準庫函數 ==》需要引用第三方模塊或其他模塊,帶名稱使用,例如:
fmt.Println()
- 自定義函數 ==》程序員自行編寫,自己調用
1、函數定義
Go 語言函數定義格式如下:
func function_name ( [parameter list] ) [return_types] {函數體
}
示例:
func add (a, b int) int {return a + b
}
函數定義解析
func
:函數由?func
?開始聲明function_name
:函數名稱,函數名和參數列表一起構成了函數簽名。注意:首字母大寫表示公開函數,首字母小寫是私有函數。parameter list
:參數列表,參數就像一個占位符,當函數被調用時,你可以將值傳遞給參數,這個值被稱為實際參數。參數列表指定的是參數類型、順序及參數個數。參數是可選的,也就是說函數也可以不包含參數。return_types
:返回類型,函數返回一列值。return_types
?是該列值的數據類型。有些功能不需要返回值,這種情況下?return_types
?不是必須的。- 函數體:函數定義的代碼集合。
實例
以下實例為?max()
?函數的代碼,該函數傳入兩個整型參數?num1
?和?num2
,并返回這兩個參數的最大值:
/* 函數返回兩個數的最大值 */
func max (num1, num2 int) int {/* 聲明局部變量 */var result intif (num1 > num2) {result = num1} else {result = num2}return result
}
2、函數調用
當創建函數時,你定義了函數需要做什么,通過調用該函數來執行指定任務。調用函數,向函數傳遞參數,并返回值,例如:
package main
import "fmt"func main() {/* 定義局部變量 */var a int = 100var b int = 200var ret int/* 調用函數并返回最大值 */ret = max(a, b) // a, b 實參fmt.Printf( "最大值是 : %d\n", ret )
}/* 函數返回兩個數的最大值 */
// num1,num2 是形參
func max(num1, num2 int) int {/* 定義局部變量 */var result intif (num1 > num2) {result = num1} else {result = num2}return result
}
以上實例在?main()
?函數中調用?max()
?函數,執行結果為:
最大值是 : 200
3、函數參數
函數如果使用參數,該變量可稱為函數的形參。形參就像定義在函數體內的局部變量。
調用函數,可以通過兩種方式來傳遞參數:
值傳遞
傳遞是指在調用函數時將實際參數復制一份傳遞到函數中,這樣在函數中如果對參數進行修改,將不會影響到實際參數。
默認情況下,Go 語言使用的是值傳遞,即在調用過程中不會影響到實際參數。
接下來,讓我們使用值傳遞來調用?swap()
?函數:
package main
import "fmt"func main() {/* 定義局部變量 */var a int = 100var b int = 200fmt.Printf("交換前 a 的值為 : %d\n", a )fmt.Printf("交換前 b 的值為 : %d\n", b )/* 通過調用函數來交換值 */swap(a, b) // 值傳遞,a ==》x,b ==》yfmt.Printf("交換后 a 的值 : %d\n", a )fmt.Printf("交換后 b 的值 : %d\n", b )
}/* 定義相互交換值的函數 */
func swap(x, y int) int {var temp inttemp = x /* 保存 x 的值 */x = y /* 將 y 值賦給 x */y = temp /* 將 temp 值賦給 y*/return temp;
}
程序中使用的是值傳遞,所以兩個值并沒有實現交互,我們可以使用引用傳遞來實現交換效果。
引用傳遞
引用傳遞是指在調用函數時將實際參數的地址傳遞到函數中,那么在函數中對參數所進行的修改,將影響到實際參數。
引用傳遞指針參數傳遞到函數內,以下是交換函數?swap()
?使用了引用傳遞:
以下我們通過使用引用傳遞來調用?swap()
?函數:
package main
import "fmt"func main() {/* 定義局部變量 */var a int = 100var b int = 200fmt.Printf("交換前,a 的值 : %d\n", a )fmt.Printf("交換前,b 的值 : %d\n", b )/* 調用 swap() 函數* &a 指向 a 指針,a 變量的地址* &b 指向 b 指針,b 變量的地址*/swap(&a, &b) // 引用傳遞,&a ===》x,&b ===》yfmt.Printf("交換后,a 的值 : %d\n", a )fmt.Printf("交換后,b 的值 : %d\n", b )
}func swap(x *int, y *int) {var temp inttemp = *x /* 保存 x 地址上的值 */*x = *y /* 將 y 值賦給 x */*y = temp /* 將 temp 值賦給 y */
}
4、函數返回多個值
Go 函數可以返回多個值,例如:
package main
import "fmt"func swap(x, y string) (string, string) {return y, x
}func main() {a, b := swap("Mahesh", "Kumar")fmt.Println(a, b)
}
以上實例執行結果為:
Kumar Mahesh
5、defer 語句
Go 語言中的?defer
?語句會將其后面跟隨的語句進行延遲處理。在?defer
?所屬的函數即將返回時,將延遲處理的語句按照?defer
?定義的順序逆序執行,即先進后出。
package main
import "fmt"func main() {fmt.Println("開始")defer fmt.Println(1)defer fmt.Println(2)defer fmt.Println(3)fmt.Println("結束")
}
以上代碼執行結果如下:
開始
結束
3
2
1
6、init 函數
每一個源文件都可以包含一個?init
?函數,該函數會在?main
?函數執行前,被 Go 框架調用,也就是說?init()
?函數會在?main()
?函數之前執行。