這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
本文為轉載,原文:Golang 學習筆記(2)—— 函數
函數定義
函數
是每一門開發語言的最基礎的組件,下面看下go語言中的函數是怎麼定義的:
func Add(a, b int)int{ return a + b}
func
是定義函數的關鍵字,Add
是函數名稱,int
是傳回值,小括弧內是函數的參數。可以隨意安排函數定義的順序,go在編譯時間會掃描所以的檔案。
多傳回值
go中函數支援多傳回值,可以返回任意數量的傳回值。多值返回在Go語言中是經常被用到的,比如,一個函數同時返回結果和異常。
下面我們看一個例子,divide
函數是計算a/b的結果,返回商和餘數。
package mainimport "fmt"func main(){ quotient, remainder := divide(5, 3) fmt.Println("商為:", quotient, "餘數為:", remainder)}func divide(a, b int)(int, int){ quotient := a / b remainder := a % b return quotient, remainder}
變參函數
go中的函數支援變參,變參就是說函數可以有任意數量的參數。變參本質上就是一個slice
,且必須是最後一個參數
。將slice
傳遞給變參函數時,注意用...
展開,否則就當做單個參數處理了。
請看以下例子:
package mainimport "fmt"func main(){ result := sum(3,5,7,9) fmt.Println("結果為:", result)}func sum(aregs ...int) int { s := 0 for _, number := range aregs{ s += number } return s}
至於什麼是
slice
,
range
又是什麼鬼,在後面講到數組的數組的時候詳細介紹,
slice
就相當於數組,
range
類似一個迴圈,迴圈每個字元素的key, value。另外其中的
_
表示不接受改傳回值。
defer
defer是go語言所特有的,defer的作用是順延強制
,在函數返回前,按照棧的形式後進先出
的原則一次執行每個defer註冊的函數。這樣可以保證函數在返回前被調用,通常用來進行資源釋放,錯誤的處理,清理資料等。下面是一個讀檔案的例子。
package mainimport "fmt"import "os"func main(){ str, err := readFile("main.go") if err != nil{ fmt.Println(err.Error()) return } fmt.Println(str)}func readFile(strFileName string)(string, error){ f, err := os.Open(strFileName) if err != nil{ fmt.Println("檔案讀取失敗") return "", err } defer f.Close() buf := make([]byte, 1024) var strContent string = "" for{ n, _ := f.Read(buf) if n == 0{ break } strContent += string(buf[0:n]) } return strContent, nil}
函數類型
函數也是一種類型,擁有相同的參數,相同的傳回值的函數,是同一種類型。用type
來定義函數類型。下面例子中display
函數輸出大於5的數值。
package mainimport "fmt"type MyFuncType func(int) boolfunc isBigThan5(n int)bool{ return n > 5}func display(arr []int, f MyFuncType){ for _, v := range arr{ if f(v){ fmt.Println(v) } }}func main(){ arr := []int{1,2,3,4,5,6,7,8,9} display(arr, isBigThan5)}
在上面的例子中,
type MyFuncType func(int) bool
定義了一個函數類型,將其命名為
MyFuncType
,接受一個int類型的參數,並返回一個bool類型的結果。
isBigThan5
是
MyFuncType
類型的函數,函數類型。跟C裡的函數指標有點像,他是可以把函數當做參數傳入到另一個函數裡,也有點像委託。
錯誤處理
go語言中沒有try...catch...finally...
這種結構化異常處理,而是用panic
代替throw
跑出異常。使用recover
函數來捕獲異常。Recover
僅在defer
函數中使用才能捕獲到異常,此時函數的執行流程已經中斷,無法恢複到後續位置繼續執行。
package mainimport "fmt"func main(){ test()}func test(){ defer func (){ if err := recover(); err != nil{ fmt.Println(err) } }() divide(5,0) fmt.Println("end of test")}func divide(a, b int) int{ return a / b}
完
本文為原創,轉載請註明出處
上一節:Golang 學習筆記(1)—— 基礎