<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Go語言defer分析

      什么是defer?

      defer語句是專門在函數(shù)結(jié)束以后做一些清理工作的。我們先舉一個例子來更好的理解,現(xiàn)在有一個函數(shù),它的作用是把一個文件內(nèi)容拷貝到另一個文件。

      func CopyFile(dstName string, srcName string) (written int64, err error) {
      	src, err := os.Open(srcName)
      	if err != nil {
      		return
      	}
      
      	dst, err := os.Create(dstName)
      	if err != nil {
      		return
      	}
      
      	written, err = io.Copy(dst, src)
      	src.Close()
      	dst.Close()
      	return
      }
      

      以上代碼是可以正常執(zhí)行的,但是存在一個問題,如果os.Create執(zhí)行失敗,那么就無法執(zhí)行到文件資源的Close函數(shù)。進程每打開一個文件就會占用一個文件描述符,而在系統(tǒng)當(dāng)中,文件描述符是有上限的,可以通過ulimit -n查看,如果資源沒有被及時釋放,會出現(xiàn)資源浪費的情況。如果打開文件過多,也會出現(xiàn)Too many open files的提示。這個時候就需要通過defer來解決問題了,代碼如下。

      func CopyFile(dstName string, srcName string) (written int64, err error) {
      	src, err := os.Open(srcName)
      	if err != nil {
      		return
      	}
      	defer src.Close()
      
      	dst, err := os.Create(dstName)
      	if err != nil {
      		return
      	}
      	defer dst.Close()
      
      	written, err = io.Copy(dst, src)
      	return
      }
      

      defer語句會在return參數(shù)設(shè)置之后、函數(shù)返回給調(diào)用者之前執(zhí)行,這樣就不再擔(dān)心文件資源無法被Close了。

      defer的三個規(guī)則

      規(guī)則一:被deferred的函數(shù)參數(shù)在defer時確定

      func a() {
      	i := 0
      	defer fmt.Println(i)
      	i++
      	return
      }
      

      我們通過以上代碼來理解這個拗口的規(guī)則,如果根據(jù)官方的定義來理解這段代碼,變量i的值鐵定為1,但實際執(zhí)行的結(jié)果不是1,卻是0。

      Each time a "defer" statement executes, the function value and parameters to the call are evaluated as usual and saved anew but the actual function is not invoked. Instead, deferred functions are invoked immediately before the surrounding function returns, in the reverse order they were deferred.

      那我們再重新來理解這個規(guī)則,變量i是在逐行執(zhí)行到defer語句的時候就已經(jīng)確定了值,這個時候變量i還沒有進行自增,所以輸出的結(jié)果應(yīng)該是0而不是1。

      規(guī)則二:被deferred函數(shù)執(zhí)行順序遵循LIFO原則

      func b() {
          for i := 0; i < 4; i++ {
              defer fmt.Print(i)
          }
      }
      

      LIFO全稱為Last In First Out,意為后進先出,棧是一種典型的LIFO數(shù)據(jù)結(jié)構(gòu)。defer也是如此,拿以上代碼為例,先后遍歷了四次,也就是做了四次壓棧操作。同理,在函數(shù)return之前,就會逐一出棧,倒序執(zhí)行defer語句,所以上述代碼輸出內(nèi)容為3210

      規(guī)則三:deferred函數(shù)可以讀取和修改函數(shù)的返回值

      func c() (i int) {
      	defer func() { i++ }()
      	return 1
      }
      

      我們定義一個defer函數(shù),將變量i自增,那么最終變量i的值為2。我們從官方文檔中可以看出,defer語句是在函數(shù)設(shè)置返回值后,且在返回給主調(diào)函數(shù)前執(zhí)行的,根據(jù)這個思路,c函數(shù)已經(jīng)return了1,這個時候執(zhí)行了defer函數(shù),將返回的結(jié)果1進行了自增,然后返回給主調(diào)函數(shù),這個時候主調(diào)函數(shù)拿到的值就是2了。

      deferred functions are executed after any result parameters are set by that return statement but before the function returns to its caller

      posted @ 2020-03-24 22:26  MARIOOW  閱讀(556)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 一本一道av无码中文字幕麻豆| av一区二区中文字幕| 亚洲精品电影院| 国产精品露脸视频观看| 国产一区二区三区在线观| 日韩在线观看中文字幕| 国产国拍亚洲精品永久软件 | 免费无码一区无码东京热| 久青草国产综合视频在线| 国产精品久久久久精品日日| 99国精品午夜福利视频不卡99| 免费成人网一区二区天堂| 91无码人妻精品一区二区蜜桃| 久久天天躁狠狠躁夜夜躁2o2o| 精品精品久久宅男的天堂| 色综合久久中文综合久久激情| 亚洲欧美日韩综合久久| 国产精品一区二区三区蜜臀| 久久国产成人午夜av影院| 欧美日本一区二区视频在线观看| 国产一国产精品免费播放| 欧美猛少妇色xxxxx| 男女无遮挡激情视频| 久热伊人精品国产中文| 久久婷婷五月综合色精品| 少妇人妻激情乱人伦| 中文字幕av日韩有码| 阿城市| 国产在线啪| 国产99在线 | 免费| 国产精品高清中文字幕| 中文字幕日韩精品有码| 国产成人精品无码免费看| 国产精品一二二区视在线| 久青草视频在线免费观看| 人妻激情偷乱一区二区三区| 日韩精品亚洲国产成人av| 久久精品蜜芽亚洲国产AV| 四虎国产精品永久在线下载| 色综合夜夜嗨亚洲一二区| 久久国产免费观看精品3|