欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go Slice進(jìn)行參數(shù)傳遞如何實(shí)現(xiàn)詳解

 更新時(shí)間:2022年12月12日 10:55:55   作者:捶捶自己  
這篇文章主要為大家介紹了Go Slice進(jìn)行參數(shù)傳遞如何實(shí)現(xiàn)的過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

先了解什么是defer

Go語言中的defer與return執(zhí)行的先后順序

Go語言的 defer 語句會(huì)將其后面跟隨的語句進(jìn)行延遲處理,在 defer 歸屬的函數(shù)即將返回時(shí),將延遲處理的語句按 defer 的逆序進(jìn)行執(zhí)行.也就是說,先被 defer 的語句最后被執(zhí)行,最后被 defer 的語句,最先被執(zhí)行。(與棧的先入后出是一個(gè)道理,也可以將其理解為入棧和出棧)

舉一個(gè)簡(jiǎn)單的例子

func main() {
   a, b := 111, 333
   defer fmt.Println("b= ", b)
   fmt.Println("a= ", a)
}
打印結(jié)果:
a=  111
b=  333

可以看到雖然執(zhí)行語句時(shí)b在前,但是輸出結(jié)果為b在最后被輸出。

defer 的用法

(簡(jiǎn)單講解,細(xì)節(jié)請(qǐng)自行查閱資料)

一般用來釋放資源或者讀寫操作,當(dāng)處理業(yè)務(wù)或邏輯中涉及成對(duì)的操作是一件比較煩瑣的事情,比如打開和關(guān)閉文件、接收請(qǐng)求和回復(fù)請(qǐng)求、加鎖和解鎖等。在這些操作中,最容易忽略的就是在每個(gè)函數(shù)退出處正確地釋放和關(guān)閉資源。比如下面一個(gè)例子

func main(){
    a := 1
    out := bufio.NewWriter(os.Stdout)
    defer out.Flush()
    fmt.Fprintln(out, a)
}
輸出結(jié)果:
1

就可以在最后將結(jié)果打印到控制臺(tái)中去,類似的用法如關(guān)閉數(shù)據(jù)庫(kù)資源等等。如果這個(gè)例子太過于簡(jiǎn)單,那么來看下個(gè)例子。

var a bool = true
defer func() {
   fmt.Println("1")
}()
if a == true {
   fmt.Println("2")
   return
}
defer func() {
   fmt.Println("3")
}()
輸出結(jié)果:
2
1

我們會(huì)發(fā)現(xiàn)defer語句也是需要被執(zhí)行的,如果在defer函數(shù)執(zhí)行之前就執(zhí)行return。defer后的語句就不會(huì)再被執(zhí)行了。但是如果是在return之前defer已經(jīng)執(zhí)行,則defer中的語句將會(huì)在return執(zhí)行之前先一步進(jìn)行執(zhí)行.

那么defer 和 return有什么聯(lián)系?

defer 是延遲執(zhí)行語句,return是返回語句,那么肯定出現(xiàn)誰先誰后的問題。下面看一個(gè)經(jīng)典的例子吧

func increaseA() int {
	var i int
	defer func() {
		i++
	}()
	return i
}
func increaseB() (r int) {
	defer func() {
		r++
	}()
	return r
}
func main() {
	fmt.Println(increaseA())
	fmt.Println(increaseB())
}
輸出結(jié)果為:
0
1

肯定有人覺得有疑惑,為什么A函數(shù)沒有輸出,B函數(shù)卻輸出了呢?為什么答案不是1和0呢?

原因:

先說結(jié)論:defer 修飾的匿名函數(shù),只能更新具名返回值.那么這會(huì)導(dǎo)致什么問題呢?我們來逐步分析這個(gè)例子。

  • 在increaseA()函數(shù)中有一個(gè)聲明i,表示i在該函數(shù)內(nèi)已經(jīng)被生成,是有名稱的變量。但該函數(shù)返回參數(shù)為匿名參數(shù).
  • 在increaseB()函數(shù)中沒有聲明r,是匿名變量。但該函數(shù)返回參數(shù)為具名參數(shù).
  • func increaseA() int,返回值i=0的時(shí)候該值已經(jīng)被綁定到返回值里了,defer再去改i已經(jīng)沒用了.
  • func increaseB() (r int), 返回值r先把返回變量設(shè)為0,defer又把r改為1.這時(shí)候還能生效. 因此答案很明顯為 1 和 0.

更進(jìn)一步理解

我們?nèi)粝胍M(jìn)一步理解也可以去輸出匯編語句,然后進(jìn)行研讀,可惜我是個(gè)菜鳥讀不懂匯編語言!但我們可以從return入手

我們要理解return 返回值的運(yùn)行機(jī)制:

return并非原子操作,分為賦值,和返回值兩步操作.實(shí)際上return 執(zhí)行了兩步操作,因?yàn)榉祷刂禌]有命名,所以return默認(rèn)指定了一個(gè)返回值(假設(shè)為a),首先將i賦值給a,后續(xù)的操作因?yàn)槭轻槍?duì)i進(jìn)行的,所以不會(huì)影響a, 此后因?yàn)閍不會(huì)更新,所以return a不會(huì)改變.

var i int  
a := i  
return a

但是如果return的參數(shù)a是具名參數(shù),就像上述例子中increaseB()函數(shù)一樣。a就相當(dāng)于命名的變量i, 因?yàn)樗械牟僮鞫际腔诿兞縤(a),返回值也是i, 所以每一次defer操作,都會(huì)更新返回值i.

省流小結(jié)

return會(huì)將返回值先保存起來,對(duì)于無名返回值來說,保存在一個(gè)臨時(shí)對(duì)象中,defer是看不到這個(gè)臨時(shí)對(duì)象的;而對(duì)于有名返回值來說,就保存在已命名的變量中。

以上就是Go語言defer與return執(zhí)行的先后順序詳解的詳細(xì)內(nèi)容,更多關(guān)于Go defer return執(zhí)行順序的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Golang自動(dòng)追蹤GitHub上熱門AI項(xiàng)目

    Golang自動(dòng)追蹤GitHub上熱門AI項(xiàng)目

    這篇文章主要為大家介紹了Golang自動(dòng)追蹤GitHub上熱門AI項(xiàng)目,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • go語言分布式id生成器及分布式鎖介紹

    go語言分布式id生成器及分布式鎖介紹

    這篇文章主要為大家介紹了go語言分布式id生成器及分布式鎖介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • Go環(huán)境變量配置,及GOROOT、GOPATH的區(qū)別小結(jié)

    Go環(huán)境變量配置,及GOROOT、GOPATH的區(qū)別小結(jié)

    本文主要介紹了Go環(huán)境變量配置,及GOROOT、GOPATH的區(qū)別小結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-09-09
  • 深入刨析Golang-map底層原理

    深入刨析Golang-map底層原理

    這篇文章主要介紹了深入刨析Golang-map底層原理,Go 語言的 map 的使用非常簡(jiǎn)易, 但其內(nèi)部實(shí)現(xiàn)相對(duì)比較復(fù)雜,文中有相關(guān)的代碼示例,,需要的朋友可以參考下
    2023-05-05
  • go reflect要不要傳指針原理詳解

    go reflect要不要傳指針原理詳解

    這篇文章主要為大家介紹了go reflect要不要傳指針原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • Go中init()執(zhí)行順序詳解

    Go中init()執(zhí)行順序詳解

    go允許定義多個(gè)init(),多個(gè)init()會(huì)涉及到執(zhí)行先后的問題,本文將詳細(xì)講解Go中init()執(zhí)行順序,感興趣的朋友一起看看吧
    2022-09-09
  • 一文初探?Goroutine?與?channel基本用法

    一文初探?Goroutine?與?channel基本用法

    這篇文章主要為大家介紹了一文初探?Goroutine?與?channel基本用法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • Go語言入門學(xué)習(xí)之Channel通道詳解

    Go語言入門學(xué)習(xí)之Channel通道詳解

    go routine可以使用channel來進(jìn)行通信,使用通信的手段來共享內(nèi)存,下面這篇文章主要給大家介紹了關(guān)于Go語言入門學(xué)習(xí)之Channel通道的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • Golang中channel的原理解讀(推薦)

    Golang中channel的原理解讀(推薦)

    channel主要是為了實(shí)現(xiàn)go的并發(fā)特性,用于并發(fā)通信的,也就是在不同的協(xié)程單元goroutine之間同步通信。接下來通過本文給大家介紹Golang中channel的原理解讀,感興趣的朋友一起看看吧
    2021-10-10
  • GoLang中的timer定時(shí)器實(shí)現(xiàn)原理分析

    GoLang中的timer定時(shí)器實(shí)現(xiàn)原理分析

    Timer中對(duì)外暴露的只有一個(gè)channel,這個(gè) channel也是定時(shí)器的核心。當(dāng)計(jì)時(shí)結(jié)束時(shí),Timer會(huì)發(fā)送值到channel中,外部環(huán)境在這個(gè) channel 收到值的時(shí)候,就代表計(jì)時(shí)器超時(shí)了,可與select搭配執(zhí)行一些超時(shí)邏輯
    2023-02-02

最新評(píng)論