Golang學習摘錄三:函數

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

函數定義

type mytype int    // 新的類型func (p mytype) funcname(q int) (r,s int) {return 0,0}

範圍

在 Go 中,定義在函數外的變數是全域的,那些定義在函數內部的變數,對於函數來說 是局部的。如果命名覆蓋——一個局部變數與一個全域變數有相同的名字——在函數 執行的時候,局部變數將覆蓋全域變數。

多值返回

func (file *File) Write(b []byte) (n int, err error)
Go得函數可以返回多個值

命名傳回值

Go 函數的傳回值或者結果參數可以指定一個名字,並且像原始的變數那樣使用,就像 輸入參數那樣。如果對其命名,在函數開始時,它們會用其類型的零值初始化。如果 函數在不加參數的情況下執行了 return 語句,結果參數會返回。
例:

func ReadFull(r Reader, buf []byte) (n int, err error) {  for len(buf) > 0 && err == nil {    var nr int    nr, err = r.Read(buf) n += nr    buf = buf[nr:len(buf)]  }  return }

延遲代碼defer

在 defer 後指定的 函數會在函數退出前調用。

func ReadWrite() bool {  file.Open("file")  defer file.Close()      // file.Close()被添加到了defer列表  if failureX {    return false  }  if failureY {    return false   }    return true}

可以將多個函數放入 “延遲列表”中,例如:

for i:=0; i<5; i++ {defer fmt.Printf("%d ", i)}// 延遲的函數是按照後進先出(LIFO)的順序執行,所以上面的代碼列印:4 3 2 1 0。

利用 defer 甚至可以修改傳回值,假設正在使用命名結果參數和函數符號。

defer func() {/* ... */}()  // ()在這裡是必須的

或者這個例子,更加容易瞭解為什麼,以及在哪裡需要括弧:

defer func(x int) { /* ... */}(5) // 為輸入參數 x 賦值 5

在這個(匿名)函數中,可以訪問任何命名返回參數:

func f() (ret int) { //ret初始化為零   defer func() {    ret++  //ret增加為1  }()   return 0    // 返回的是1而不是0}

變參

接受不定數量的參數的函數叫做變參函數。定義函數使其接受變參:
func myfunc(arg ...int) { }
arg ...int 告訴 Go 這個函數接受不定數量的參數。注意,這些參數的類型全部是 int。
在函數體中,變數 arg 是一個 int 類型的 slice:

for _, n := range arg {  fmt.Printf("And the number is: %d\n", n)}

如果不指定變參的類型,預設是空的介面 interface{}(參閱第 5 章)。假設有另一
個變參函數叫做 myfunc2,下面的例子示範了如何向其傳遞變參:

func myfunc(arg ...int) { myfunc2(arg...) ← 按原樣傳遞  myfunc2(arg[:2]...) ← 傳遞部分}

函數作為值

Go 中函數也是值,函數可以賦值給變數:

func main() {  a := func() {      // 定義一個匿名函數,並賦值給a    println("Hello")  }  a()  // 調用函數}

回調

由於函數也是值,所以可以很容易的傳遞到其他函數裡,然後可以作為回調。

func printit(x int) { // 函數無傳回值   fmt.Printf("%v\n", x) // 僅僅列印}func callback(y int, f func(int)) { // f 將會儲存函數   f(y) // 調用回呼函數 f 輸入變數 y}

恐慌(Panic)和恢複(Recover)

Panic:是一個內建函數,可以中斷原有的控制流程程,進入一個令人恐慌的流程中。當函數F調用panic,函數F的執行被中斷,並且F中的延遲函數會正常執行,然後F返回到調用它的地方。在調用的地方,F的行為就像調用了panic。這一過程繼續向上,直到程式崩潰時所有goroutine返回。
恐慌可以直接調用panic產生。也可以由執行階段錯誤產生,例如訪問越界的數組。
Recover:是一個內建函數,可以讓進入令人恐慌的流程中的goroutine恢複過來。recover僅在延遲函數中有效。
在正常的執行過程中,調用recover會返回nil並且沒有其他任何效果。如果當期的goroutine陷入恐慌,調用recover可以捕獲到panic的輸入值,並且恢複正常的執行。
例:

這個函數檢查作為其參數的函數在執行時是否會產生 panic c: . func throwsPanic(f func()) (b bool) {//定義一個新函數 throwsPanic 接受一個函數作為參數(參看 “函數作為值”)。函 數 f 產生 panic,就返回 true,否則返回 false;  defer func() { //定義了一個利用 recover 的 defer 函數。如果當前的 goroutine 產生了 panic,這個 defer 函數能夠發現。當 recover() 返回非 nil 值,設定 b 為 true;     if x := recover(); x != nil {          b = true      }   }() f() // 調用作為參數接收的函數。 return // 返回 b 的值。由於 b 是命名傳回值,無須指定 b。}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.