Golang 函數function

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

函數function

  • Go函數不支援嵌套、重載和預設參數
  • 但支援以下特性:
  1. 無需聲明原型
  2. 不定長度變參
  3. 多傳回值
  4. 命名傳回值參數
  5. 匿名函數
  6. 閉包
  • 定義函數使用關鍵字func,且左大括弧不能另起一行
  • 函數也可以作為一種類型使用

傳回值及參數說明

func A(a int, b string) (int, string, int)  { //第一個小括弧當中是你的參數列表,第二個小括弧是你的傳回值列表    }
func A(a, b, c int) (int, string, int)  {    //如果abc都是int型的話,可以按照這種方法進行簡寫,同樣的方法也適用於傳回值當中}
func A() (a, b, c int)  { //1:如果這樣寫的話就必須要命名傳回值    //命名傳回值和不命名傳回值得區別}
func A() (int, int, int)  { //    //命名傳回值和不命名傳回值得區別    a, b, c := 1,2,3    return a,b,c    //如果此時沒有命名傳回值的時候,那麼在傳回值得時候就必須寫上return a,b,c    //當然為了代碼的可讀性,這裡我們規定必須return 的時候加上傳回值名}

不定長變參

package mainimport "fmt"func main()  {    A(1,2,3,4,5,6,7)}func A(a ...int) {    // 這裡採用的是不定長變參,不定長變參必須是參數的最後一個參數,後面不能再跟 b string這樣的參數    fmt.Println(a)}
package mainimport "fmt"func main()  {    s1:= []int{1,2,3,4}    a,b :=1,2    A(a,b)    fmt.Println(a,b)    B(s1)    fmt.Println(s1)}func A(a ...int) {    //這裡傳進來的實際上是一個slice,參考型別    a[0] = 3    a[1] = 4    //儘管我們在函數A當中接收到的是一個slice,但是它得到的是一個值拷貝    //和直接傳遞一個slice的區別看函數B    fmt.Println(a)}func B(s []int)  {    //這裡並不是傳遞一個指標進去,而是對這個slice的記憶體位址進行了一個拷貝    //這裡還可以看到像int型、string型進行常規的參數傳進去的話,只是進行了個值拷貝,slice傳進去雖然也是拷貝,但是它是記憶體位址的拷貝    s[0] = 4    s[1] = 5    s[2] = 6    s[3] = 7    fmt.Println(s)    //在這裡 我們看到我們在函數B當中的修改,實際上影響到了我們main函數當中的變數s1    //如果直接傳遞一個slice,它的修改就會影響到這個slice的本身}PS:實值型別和參考型別進行函數傳參拷貝是不一樣的,一個是拷貝值,一個是拷貝地址
package mainimport (    "fmt")func main() {    a := 1    A(&a) //這裡取出a的地址    fmt.Println(a)}func A(a *int) { //傳遞的是指標類型    *a = 2 //在操作的時候需要去它的值進行操作,這個時候函數A就可以改變原始a的值    fmt.Println(*a)}

函數類型的使用

package mainimport (    "fmt")func main() {    a := A    a() //這個時候是將A的函數類型賦值給a,在go語言當中一切皆是類型啊}func A() {    fmt.Println("Func A")}

匿名函數的使用

package mainimport (    "fmt")func main() {    a := func() {        //此時這個代碼塊就是一個匿名函數,這個函數本身沒有名稱,我們將她賦值給a,然後調用        fmt.Println("Func A")    }    a() //依然可以列印func A}

GO語言當中的閉包

package mainimport (    "fmt")func main() {    f := closure(10)    res1 := f(1)    fmt.Println(res1)    res2 := f(2)    fmt.Println(res2)}func closure(x int) func(int) int {    fmt.Printf("%p \n", &x)    return func(y int) int {        fmt.Printf("%p \n", &x)        return x + y    }}//這裡可以看出3次列印x的地址都是一樣的

defer

  • defer的執行方式類似其它語言中的解構函式,在函數執行體結束後按照調用順序的相反順序逐個執行
  • 即使函數發生嚴重錯誤也會執行
  • 支援匿名函數的調用
  • 通常用於資源清理、檔案關閉、解鎖以及記錄時間等操作
  • 通過與匿名函數配合可在return之後修改Function Compute結果
  • 如果函數體內某個變數作為defer時匿名函數的參數,則在定義defer時即已經獲得了拷貝,否則則是引用某個變數的地址

  • GO沒有異常機制,但有panic/recove模式來處理錯誤
  • Panic可以在任何地方引發,但recover只有在defer調用的函數中有效

package mainimport (    "fmt")func main() {    fmt.Println("A")    defer fmt.Println("B")    defer fmt.Println("C")}//PS:列印的結果就是A C B
package mainimport (    "fmt")func main() {    for i := 0; i < 3; i++ {        //defer fmt.Println(i)        defer func() {            fmt.Println(i)        }() //調用這個函數    }}//剛才直接列印的時候,是作為一個參數傳遞進去,運行到defer的時候是將這個i的值進行了一個拷貝,所以列印的是 2 1 0//這種情況下i一直是一個地址的引用,i一直引用的是局部變數的i,在退出這個迴圈體的時候 i已經變成了3,在main函數return的時候,開始執行defer語句,defer語句的時候i已經變成了3

異常機制

package mainimport (    "fmt")func main() {    A()    B()    C()}func A() {    fmt.Println("Func A")}func B() {    defer func() {        if err := recover(); err != nil {            fmt.Println("Recover in B")        }    }()    panic("Panic in B")}func C() {    fmt.Println("Func C")}
package mainimport (    "fmt")func main() {    var fs = [4]func(){}    for i := 0; i < 4; i++ {        defer fmt.Println("defer i=", i) //這個i是傳遞進來的參數,所以是值得拷貝        defer func() {            fmt.Println("defer_closure i=", i) //這裡的i是引用外部的i,所以迴圈結束後,i變成了4        }()        fs[i] = func() {            fmt.Println("closure i = ", i) //這裡也是引用外部的i,所以迴圈結束後i變成了4        }    }    for _, f := range fs {        f()    }}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.