欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

go語(yǔ)言函數(shù)調(diào)用時(shí)間 go語(yǔ)言常用函數(shù)

簡(jiǎn)單聊聊Golang中defer預(yù)計(jì)算參數(shù)

什么是defer

創(chuàng)新互聯(lián)建站主營(yíng)建湖網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,app軟件定制開(kāi)發(fā),建湖h5小程序定制開(kāi)發(fā)搭建,建湖網(wǎng)站營(yíng)銷(xiāo)推廣歡迎建湖等地區(qū)企業(yè)咨詢

defer 可以保證方法可以在外圍函數(shù)返回之前調(diào)用。有點(diǎn)像其他言的 try finally

Go語(yǔ)言defer預(yù)計(jì)算參數(shù)

Go 語(yǔ)言中所有的函數(shù)調(diào)用都是傳值的,雖然 defer 是關(guān)鍵字,但是也繼承了這個(gè)特性。假設(shè)我們想要計(jì)算 main 函數(shù)運(yùn)行的時(shí)間,可能會(huì)寫(xiě)出以下的代碼:

結(jié)果是:

運(yùn)行結(jié)果并不符合我們的預(yù)期,這個(gè)現(xiàn)象背后的原因是什么呢?經(jīng)過(guò)分析,我們會(huì)發(fā)現(xiàn)調(diào)用 defer 關(guān)鍵字會(huì)立刻拷貝函數(shù)中引用的外部參數(shù),所以 time.Since(startedAt) 的結(jié)果不是在 main 函數(shù)退出之前計(jì)算的,而是在 defer 關(guān)鍵字調(diào)用時(shí)計(jì)算的【defer入棧的時(shí)候】,最終導(dǎo)致上述代碼輸出 0s

我們?cè)賮?lái)看個(gè)簡(jiǎn)單例子來(lái)說(shuō)明上述解釋:

當(dāng)代碼運(yùn)行到defer fmt.Println(test(i))的時(shí)候,會(huì)把defer右邊最外層函數(shù)的參數(shù)計(jì)算完畢,并傳遞進(jìn)函數(shù)里,但不會(huì)執(zhí)行函數(shù)體的代碼直到包裹defer的函數(shù)返回。我們先看會(huì)把defer右邊最外層函數(shù)的參數(shù)計(jì)算完畢,并傳遞進(jìn)函數(shù)里這句話,對(duì)應(yīng)例子就是先把test(i)算出來(lái),此時(shí)i=1,計(jì)算test(1)得2,然后fmt.Println(2)入棧,等到最后程序運(yùn)行完了再運(yùn)行defer結(jié)果就是2(但不會(huì)執(zhí)行函數(shù)體的代碼直到包裹defer的函數(shù)返回)。

我們?cè)賮?lái)看一個(gè)例子與匿名函數(shù)結(jié)合:

結(jié)果:

使用匿名函數(shù),結(jié)果是101,相當(dāng)于i給到test方法的是100,那為什么呢?還是那句話:但不會(huì)執(zhí)行函數(shù)體的代碼直到包裹defer的函數(shù)返回

也就是說(shuō)他會(huì)把整個(gè){ fmt.Println(test(i)) }()函數(shù)體入棧,等到最后程序運(yùn)行完了再運(yùn)行defer,此時(shí)的i是100,運(yùn)行test后就是101了。

所以你要解決第一個(gè)打印為0s的問(wèn)題,你就可以使用匿名函數(shù)來(lái)解決,如下:

結(jié)果:

Golang入門(mén)到項(xiàng)目實(shí)戰(zhàn) | golang 函數(shù)

函數(shù)的go語(yǔ)言中的一級(jí)公民,我們把所有的功能單元都定義在函數(shù)中,可以重復(fù)使用。函數(shù)包含函數(shù)的名稱、參數(shù)列表和返回值類型,這些構(gòu)成了函數(shù)的簽名(signature)。

函數(shù)在使用之前必須先定義,可以調(diào)用函數(shù)來(lái)完成某個(gè)任務(wù)。函數(shù)可以重復(fù)調(diào)用,從而達(dá)到代碼重用。

go語(yǔ)言函數(shù)定義語(yǔ)法

語(yǔ)法解析:

go語(yǔ)言函數(shù)定義實(shí)例

定義一個(gè)求和函數(shù)

定義一個(gè)比較兩個(gè)數(shù)大小的函數(shù)

go語(yǔ)言函數(shù)調(diào)用

當(dāng)我們要完成某個(gè)任務(wù)時(shí),可以調(diào)用函數(shù)來(lái)完成。調(diào)用函數(shù)要傳遞參數(shù),如何有返回值可以獲得返回值。

運(yùn)行結(jié)果

GO語(yǔ)言學(xué)習(xí)系列八——GO函數(shù)(func)的聲明與使用

GO是編譯性語(yǔ)言,所以函數(shù)的順序是無(wú)關(guān)緊要的,為了方便閱讀,建議入口函數(shù) main 寫(xiě)在最前面,其余函數(shù)按照功能需要進(jìn)行排列

GO的函數(shù) 不支持嵌套,重載和默認(rèn)參數(shù)

GO的函數(shù) 支持 無(wú)需聲明變量,可變長(zhǎng)度,多返回值,匿名,閉包等

GO的函數(shù)用 func 來(lái)聲明,且左大括號(hào) { 不能另起一行

一個(gè)簡(jiǎn)單的示例:

輸出為:

參數(shù):可以傳0個(gè)或多個(gè)值來(lái)供自己用

返回:通過(guò)用 return 來(lái)進(jìn)行返回

輸出為:

上面就是一個(gè)典型的多參數(shù)傳遞與多返回值

對(duì)例子的說(shuō)明:

按值傳遞:是對(duì)某個(gè)變量進(jìn)行復(fù)制,不能更改原變量的值

引用傳遞:相當(dāng)于按指針傳遞,可以同時(shí)改變?cè)瓉?lái)的值,并且消耗的內(nèi)存會(huì)更少,只有4或8個(gè)字節(jié)的消耗

在上例中,返回值 (d int, e int, f int) { 是進(jìn)行了命名,如果不想命名可以寫(xiě)成 (int,int,int){ ,返回的結(jié)果都是一樣的,但要注意:

當(dāng)返回了多個(gè)值,我們某些變量不想要,或?qū)嶋H用不到,我們可以使用 _ 來(lái)補(bǔ)位,例如上例的返回我們可以寫(xiě)成 d,_,f := test(a,b,c) ,我們不想要中間的返回值,可以以這種形式來(lái)舍棄掉

在參數(shù)后面以 變量 ... type 這種形式的,我們就要以判斷出這是一個(gè)可變長(zhǎng)度的參數(shù)

輸出為:

在上例中, strs ...string 中, strs 的實(shí)際值是b,c,d,e,這就是一個(gè)最簡(jiǎn)單的傳遞可變長(zhǎng)度的參數(shù)的例子,更多一些演變的形式,都非常類似

在GO中 defer 關(guān)鍵字非常重要,相當(dāng)于面相對(duì)像中的析構(gòu)函數(shù),也就是在某個(gè)函數(shù)執(zhí)行完成后,GO會(huì)自動(dòng)這個(gè);

如果在多層循環(huán)中函數(shù)里,都定義了 defer ,那么它的執(zhí)行順序是先進(jìn)后出;

當(dāng)某個(gè)函數(shù)出現(xiàn)嚴(yán)重錯(cuò)誤時(shí), defer 也會(huì)被調(diào)用

輸出為

這是一個(gè)最簡(jiǎn)單的測(cè)試了,當(dāng)然還有更復(fù)雜的調(diào)用,比如調(diào)試程序時(shí),判斷是哪個(gè)函數(shù)出了問(wèn)題,完全可以根據(jù) defer 打印出來(lái)的內(nèi)容來(lái)進(jìn)行判斷,非常快速,這種留給你們?nèi)?shí)現(xiàn)

一個(gè)函數(shù)在函數(shù)體內(nèi)自己調(diào)用自己我們稱之為遞歸函數(shù),在做遞歸調(diào)用時(shí),經(jīng)常會(huì)將內(nèi)存給占滿,這是非常要注意的,常用的比如,快速排序就是用的遞歸調(diào)用

本篇重點(diǎn)介紹了GO函數(shù)(func)的聲明與使用,下一篇將介紹GO的結(jié)構(gòu) struct

怎么樣使用Go語(yǔ)言中函數(shù)的參數(shù)傳遞與調(diào)用

按值傳遞函數(shù)參數(shù),是拷貝參數(shù)的實(shí)際值到函數(shù)的形式參數(shù)的方法調(diào)用。在這種情況下,參數(shù)在函數(shù)內(nèi)變化對(duì)參數(shù)不會(huì)有影響。

默認(rèn)情況下,Go編程語(yǔ)言使用調(diào)用通過(guò)值的方法來(lái)傳遞參數(shù)。在一般情況下,這意味著,在函數(shù)內(nèi)碼不能改變用來(lái)調(diào)用所述函數(shù)的參數(shù)。考慮函數(shù)swap()的定義如下。

代碼如下:

/* function definition to swap the values */

func swap(int x, int y) int {

var temp int

temp = x /* save the value of x */

x = y /* put y into x */

y = temp /* put temp into y */

return temp;

}

現(xiàn)在,讓我們通過(guò)使實(shí)際值作為在以下示例調(diào)用函數(shù)swap():

代碼如下:

package main

import "fmt"

func main() {

/* local variable definition */

var a int = 100

var b int = 200

fmt.Printf("Before swap, value of a : %d\n", a )

fmt.Printf("Before swap, value of b : %d\n", b )

/* calling a function to swap the values */

swap(a, b)

fmt.Printf("After swap, value of a : %d\n", a )

fmt.Printf("After swap, value of b : %d\n", b )

}

func swap(x, y int) int {

var temp int

temp = x /* save the value of x */

x = y /* put y into x */

y = temp /* put temp into y */

return temp;

}

讓我們把上面的代碼放在一個(gè)C文件,編譯并執(zhí)行它,它會(huì)產(chǎn)生以下結(jié)果:

Before swap, value of a :100

Before swap, value of b :200

After swap, value of a :100

After swap, value of b :200

這表明,參數(shù)值沒(méi)有被改變,雖然它們已經(jīng)在函數(shù)內(nèi)部改變。

通過(guò)傳遞函數(shù)參數(shù),即是拷貝參數(shù)的地址到形式參數(shù)的參考方法調(diào)用。在函數(shù)內(nèi)部,地址是訪問(wèn)調(diào)用中使用的實(shí)際參數(shù)。這意味著,對(duì)參數(shù)的更改會(huì)影響傳遞的參數(shù)。

要通過(guò)引用傳遞的值,參數(shù)的指針被傳遞給函數(shù)就像任何其他的值。所以,相應(yīng)的,需要聲明函數(shù)的參數(shù)為指針類型如下面的函數(shù)swap(),它的交換兩個(gè)整型變量的值指向它的參數(shù)。

代碼如下:

/* function definition to swap the values */

func swap(x *int, y *int) {

var temp int

temp = *x /* save the value at address x */

*x = *y /* put y into x */

*y = temp /* put temp into y */

}

現(xiàn)在,讓我們調(diào)用函數(shù)swap()通過(guò)引用作為在下面的示例中傳遞數(shù)值:

代碼如下:

package main

import "fmt"

func main() {

/* local variable definition */

var a int = 100

var b int= 200

fmt.Printf("Before swap, value of a : %d\n", a )

fmt.Printf("Before swap, value of b : %d\n", b )

/* calling a function to swap the values.

* a indicates pointer to a ie. address of variable a and

* b indicates pointer to b ie. address of variable b.

*/

swap(a, b)

fmt.Printf("After swap, value of a : %d\n", a )

fmt.Printf("After swap, value of b : %d\n", b )

}

func swap(x *int, y *int) {

var temp int

temp = *x /* save the value at address x */

*x = *y /* put y into x */

*y = temp /* put temp into y */

}

讓我們把上面的代碼放在一個(gè)C文件,編譯并執(zhí)行它,它會(huì)產(chǎn)生以下結(jié)果:

Before swap, value of a :100

Before swap, value of b :200

After swap, value of a :200

After swap, value of b :100

這表明變化的功能以及不同于通過(guò)值調(diào)用的外部體現(xiàn)的改變不能反映函數(shù)之外。

3.6 Go語(yǔ)言函數(shù)的延遲調(diào)用(Deferred Code)

在以下這段代碼中,我們操作一個(gè)文件,無(wú)論成功與否都需要關(guān)閉文件句柄。這里在三處不同的位置都調(diào)用了file.Close()方法,代碼顯得非常冗余。

我們利用延遲調(diào)用來(lái)優(yōu)化代碼。定義后的defer代碼,會(huì)在return之前返回,讓代碼顯得更加緊湊,且可讀性變強(qiáng),對(duì)上面的代碼改造如下:

我們通過(guò)這個(gè)示例來(lái)看一下延遲調(diào)用與正常代碼之間的執(zhí)行順序

先簡(jiǎn)單分析一下代碼邏輯:

從輸出中,我們可以觀察到如下現(xiàn)象:

從這個(gè)實(shí)例中,我們很明顯觀察到,defer語(yǔ)句是在return之前執(zhí)行

如果一個(gè)函數(shù)內(nèi)定義了多個(gè)defer,則調(diào)用順序?yàn)長(zhǎng)IFO(后進(jìn)先出)方式執(zhí)行。

仍然是相同的例子,但是在TestDefer中我們定義了三個(gè)defer輸出,根據(jù)LIFO原則,輸出的順序是3rd-2nd-1st,根據(jù)最后的結(jié)果,也是逆向向上執(zhí)行defer輸出。

就在整理這篇筆記的時(shí)候,發(fā)現(xiàn)了自己的認(rèn)知誤區(qū),主要是本節(jié)實(shí)例三中發(fā)現(xiàn)的,先來(lái)看一下英文的描述:

對(duì)于上面的這段話的理解:

下面是代碼執(zhí)行輸出,我們來(lái)一起分析一下:

雖然在a()函數(shù)內(nèi),顯示的返回了10,但是main函數(shù)中得到的結(jié)果是defer函數(shù)自增后的結(jié)果,我們來(lái)分析一下代碼:

在這篇文章的上一版,我曾經(jīng)嘗試用指針取解釋defer修改返回值的類型,但是感覺(jué)不夠透徹,也讓閱讀者非常困惑,索性參考了一下go官方blog中的一篇文章,在此基礎(chǔ)上進(jìn)行了擴(kuò)展。如需要閱讀原文,可以參考下面的文章。

淺談Go語(yǔ)言函數(shù)與方法的區(qū)別

前段時(shí)間,我們實(shí)驗(yàn)室用go作為后臺(tái)開(kāi)發(fā)語(yǔ)言開(kāi)發(fā)了一個(gè)web項(xiàng)目,由于這是自己第一次使用go語(yǔ)言進(jìn)行開(kāi)發(fā),在開(kāi)發(fā)過(guò)程中,一味著追求完成任務(wù),在編碼的時(shí)候沒(méi)有太注重性能,雖然勉強(qiáng)實(shí)現(xiàn)了功能,但是對(duì)go語(yǔ)言的理解還是比較淺顯的。下面來(lái)談?wù)勛约簩?duì)go語(yǔ)言中函數(shù)與方法的理解。

普通函數(shù):

go函數(shù)可以返回多個(gè)值

值傳遞: 值傳遞是指在調(diào)用函數(shù)時(shí)將實(shí)際參數(shù)復(fù)制一份傳遞到函數(shù)中,這樣函數(shù)中如果對(duì)參數(shù)進(jìn)行修改,將不會(huì)影響到實(shí)際參數(shù)

引用傳遞: 引用傳遞是指在調(diào)用函數(shù)將實(shí)際參數(shù)的地址傳遞到函數(shù)中,那么在函數(shù)中對(duì)參數(shù)進(jìn)行的修改,將影響到實(shí)際參數(shù)。

一般來(lái)說(shuō)go語(yǔ)言函數(shù)的 接收者(也就是形參)一般放在函數(shù)名后面 ,不能將指針類型的數(shù)據(jù)直接傳遞,也就是說(shuō)函數(shù)形參如果是值類型,調(diào)用者必須使用值作為實(shí)參過(guò)來(lái),如果函數(shù)形參是指針類型,則函數(shù)調(diào)用者需使用指針作為實(shí)參來(lái)調(diào)用。

普通方法:

接收者是在func關(guān)鍵字后面,而不是在函數(shù)名稱后面,接收者可以是自己定義的一個(gè)類型,這個(gè)類型可以是struct、interface,一個(gè)方法就是一個(gè)包含了接收者的函數(shù),接收者可以是命名類型或者是結(jié)構(gòu)體類型的一個(gè)值或者是一個(gè)指針。

下面是一個(gè)例子來(lái)說(shuō)明方法和函數(shù)的區(qū)別(重點(diǎn))

本文題目:go語(yǔ)言函數(shù)調(diào)用時(shí)間 go語(yǔ)言常用函數(shù)
文章網(wǎng)址:http://chinadenli.net/article34/dodicpe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、網(wǎng)站設(shè)計(jì)公司、ChatGPT企業(yè)網(wǎng)站制作、網(wǎng)站排名、軟件開(kāi)發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設(shè)