<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          一篇文章帶你了解Go語言基礎(chǔ)之函數(shù)(中篇)

          共 1424字,需瀏覽 3分鐘

           ·

          2020-11-12 18:34

          點擊上方“Go語言進階學(xué)習(xí)”,進行關(guān)注

          回復(fù)“Go語言”即可獲贈Python從入門到進階共10本電子書

          含光混世貴無名,何用孤高比云月??

          前言

          Hey,大家好呀,我是星期八,上篇文章學(xué)了些基礎(chǔ):一篇文章帶你了解Go語言基礎(chǔ)之函數(shù)(上篇),這次咱們繼續(xù)學(xué)習(xí)Go基礎(chǔ)之函數(shù)進階叭。

          Go函數(shù)內(nèi)存分配圖

          Go的函數(shù)內(nèi)存分配,有點像堆分配,有點像,但是本質(zhì)不是。

          可以理解像堆內(nèi)存一樣,棧中保存的是堆的地址。

          驗證

          代碼

          package main
          import "fmt"

          func say() string { return "ok"}
          func main() { fmt.Printf("say棧上的內(nèi)容:%p\n",say)}

          結(jié)果

          本質(zhì)

          函數(shù)的作用域

          作用域這個問題,以前可能或多或少提過,再來復(fù)習(xí)一下叭。

          全局變量

          全局變量就是在所有函數(shù)外部定義的變量,程序不結(jié)束,變量就一直存在。

          當(dāng)然,任何函數(shù)都可以訪問全局變量。

          注:全局變量盡量全部用大寫。

          小試牛刀

          package main
          import "fmt"

          var NAME = "張三"func say() string { fmt.Println(NAME) return "ok"}
          func main() { say() fmt.Println(NAME)}

          結(jié)果:

          上述可能會有個問題,全局變量,全局變量,大家共用一個,要是誰傻不拉幾修改了不就完蛋了,整個程序都涼了。

          var引發(fā)的問題

          就像這樣。

          package main
          import "fmt"
          var NAME = "張三"
          func say() string { fmt.Println(NAME) NAME = "李四" return "ok"}
          func main() { say() fmt.Println(NAME)}

          結(jié)果:

          這不就完犢子了嗎???所以,一定要有解決辦法。

          使用const解決問題

          解決辦法:使用常量定義全局變量。

          package main
          import "fmt"
          const NAME = "張三"
          func say() string { fmt.Println(NAME) //NAME = "李四"http://會報錯:cannot assign to NAME return "ok"}
          func main() { say() fmt.Println(NAME)
          }

          總結(jié)

          在定義全局變量時,需要用const修飾,并且變量名全部大寫。

          局部變量

          局部變量,局部變量就是在某個函數(shù)內(nèi)定義的變量,只能在自己函數(shù)內(nèi)使用。

          更專業(yè)點,在{}內(nèi)定義的,只能在{}內(nèi)使用,for同理。

          代碼

          package main
          import ( "fmt")
          func say() string { var name = "張三" fmt.Println(name) return "ok"}
          func main() { say() //fmt.Println(name)//會報錯:undefined: name //for同理 for i := 0; i <= 1; i++ { var c = "66" fmt.Println(c) //66} //fmt.Println(c)//會報錯:undefined: c}

          defer

          在Go中,defer語句,可以理解為在return之前執(zhí)行的一個語句。

          如果函數(shù)沒有return,會有一個默認的return,只是看不見而已。

          一個defer

          代碼

          package main
          import "fmt"
          func say() { //defer盡量往前放 defer fmt.Println("我是666") fmt.Println("你們都是最棒的")}
          func main() { say()}

          執(zhí)行結(jié)果

          多個defer

          代碼

          package main
          import "fmt"
          func say() { //defer盡量往前放 defer fmt.Println(1) defer fmt.Println(2) defer fmt.Println(3) fmt.Println("你們都是最棒的")}
          func main() { say()}

          執(zhí)行結(jié)果

          可以發(fā)現(xiàn),defer的執(zhí)行結(jié)果是反著的。

          結(jié)論:先執(zhí)行的defer,會最后執(zhí)行,最后執(zhí)行的defer,會最先執(zhí)行,有點像棧,先進后出

          defer的作用

          通常來說,defer會用在釋放數(shù)據(jù)庫連接,關(guān)閉文件等需要在函數(shù)結(jié)束時處理的操作。

          這里暫時先不舉例子。


          panic和recover

          這倆,可以理解為Python中的tryraise,因為在Go中,是沒有try的,是不能像其他語言一樣,try所有異常。

          應(yīng)用場景:比如某個web,在啟動時,數(shù)據(jù)庫都沒連接成功,必定要啟動失敗,就像電腦,沒有電源必不能開機一樣。

          panic

          先看一下語法吧

          package main
          import "fmt"
          func say() { var flag = true if flag{ //引發(fā)錯誤,直接中斷程序的錯誤 panic("OMG,撤了撤了,必須撤了")}}
          func main() { say() fmt.Println("繼續(xù)呀...")//不會執(zhí)行,程序掛了}

          執(zhí)行效果

          可以看淡,繼續(xù)呀就沒打印,程序直接掛了,但是上述好像并沒有解決這個問題。

          recover

          嘗試捕捉

          代碼

          package main
          import "fmt"
          func say() { //匿名函數(shù),defer執(zhí)行的是一個匿名函數(shù) defer func() { var err = recover() //如果有panic錯誤,err!=nil,在此處步驟,嘗試恢復(fù) if err != nil { fmt.Println("嘗試恢復(fù)...") } }() var flag = true if flag { panic("OMG,撤了撤了,必須撤了") }}
          func main() { say() fmt.Println("繼續(xù)呀...")}

          執(zhí)行結(jié)果

          可以看到,如果recover捕捉了,并且沒有panic,程序就會繼續(xù)正常執(zhí)行。

          注意

          defer必須在panic語句之前。

          recover必須配合defer使用。


          總結(jié)

          上述我們學(xué)習(xí)了Go基礎(chǔ)之函數(shù)進階。如果在操作過程中有任何問題,記得下面討論區(qū)留言,我們看到會第一時間解決問題。

          我是碼農(nóng)星期八,如果覺得還不錯,記得動手點贊一下哈。感謝你的觀看。

          -------------------?End?-------------------

          歡迎大家點贊轉(zhuǎn)發(fā),轉(zhuǎn)載,感謝大家的相伴與支持

          想加入學(xué)習(xí)群請在后臺回復(fù)【入群

          萬水千山總是情,點個【在看】行不行

          瀏覽 50
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产一卡在线 | 女同事的骚逼 | 天天夜激情 | 成人AV高清无码在线观 | 久久才是精品 |