GO是編譯性語(yǔ)言,所以函數(shù)的順序是無(wú)關(guān)緊要的,為了方便閱讀,建議入口函數(shù) main 寫在最前面,其余函數(shù)按照功能需要進(jìn)行排列
創(chuàng)新互聯(lián)于2013年創(chuàng)立,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作、外貿(mào)營(yíng)銷網(wǎng)站建設(shè)網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元德欽做網(wǎng)站,已為上家服務(wù),為德欽各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:18980820575
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)行了命名,如果不想命名可以寫成 (int,int,int){ ,返回的結(jié)果都是一樣的,但要注意:
當(dāng)返回了多個(gè)值,我們某些變量不想要,或?qū)嶋H用不到,我們可以使用 _ 來(lái)補(bǔ)位,例如上例的返回我們可以寫成 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
1. 保留但大幅度簡(jiǎn)化指針
Go語(yǔ)言保留著C中值和指針的區(qū)別,但是對(duì)于指針?lè)爆嵱梅ㄟM(jìn)行了大量的簡(jiǎn)化,引入引用的概念。所以在Go語(yǔ)言中,你幾乎不用擔(dān)心會(huì)因?yàn)橹苯硬僮鲀?nèi)寸而引起各式各樣的錯(cuò)誤。
2. 多參數(shù)返回
還記得在C里面為了回饋多個(gè)參數(shù),不得不開辟幾段指針傳到目標(biāo)函數(shù)中讓其操作么?在Go里面這是完全不必要的。而且多參數(shù)的支持讓Go無(wú)需使用繁瑣的exceptions體系,一個(gè)函數(shù)可以返回期待的返回值加上error,調(diào)用函數(shù)后立刻處理錯(cuò)誤信息,清晰明了。
3. Array,slice,map等內(nèi)置基本數(shù)據(jù)結(jié)構(gòu)
如果你習(xí)慣了Python中簡(jiǎn)潔的list和dict操作,在Go語(yǔ)言中,你不會(huì)感到孤單。一切都是那么熟悉,而且更加高效。如果你是C++程序員,你會(huì)發(fā)現(xiàn)你又找到了STL的vector 和 map這對(duì)朋友。
4. Interface
Go語(yǔ)言最讓人贊嘆不易的特性,就是interface的設(shè)計(jì)。任何數(shù)據(jù)結(jié)構(gòu),只要實(shí)現(xiàn)了interface所定義的函數(shù),自動(dòng)就implement了這個(gè)interface,沒(méi)有像Java那樣冗長(zhǎng)的class申明,提供了靈活太多的設(shè)計(jì)度和OO抽象度,讓你的代碼也非常干凈。千萬(wàn)不要以為你習(xí)慣了Java那種一條一條加implements的方式,感覺(jué)還行,等接口的設(shè)計(jì)越來(lái)越復(fù)雜的時(shí)候,無(wú)數(shù)Bug正在后面等著你。
同時(shí),正因?yàn)槿绱耍珿o語(yǔ)言的interface可以用來(lái)表示任何generic的東西,比如一個(gè)空的interface,可以是string可以是int,可以是任何數(shù)據(jù)類型,因?yàn)檫@些數(shù)據(jù)類型都不需要實(shí)現(xiàn)任何函數(shù),自然就滿足空interface的定義了。加上Go語(yǔ)言的type assertion,可以提供一般動(dòng)態(tài)語(yǔ)言才有的duck typing特性, 而仍然能在compile中捕捉明顯的錯(cuò)誤。
5. OO
Go語(yǔ)言本質(zhì)上不是面向?qū)ο笳Z(yǔ)言,它還是過(guò)程化的。但是,在Go語(yǔ)言中, 你可以很輕易的做大部分你在別的OO語(yǔ)言中能做的事,用更簡(jiǎn)單清晰的邏輯。是的,在這里,不需要class,仍然可以繼承,仍然可以多態(tài),但是速度卻快得多。因?yàn)楸举|(zhì)上,OO在Go語(yǔ)言中,就是普通的struct操作。
6. Goroutine
這個(gè)幾乎算是Go語(yǔ)言的招牌特性之一了,我也不想多提。如果你完全不了解Goroutine,那么你只需要知道,這玩意是超級(jí)輕量級(jí)的類似線程的東西,但通過(guò)它,你不需要復(fù)雜的線程操作鎖操作,不需要care調(diào)度,就能玩轉(zhuǎn)基本的并行程序。在Go語(yǔ)言里,觸發(fā)一個(gè)routine和erlang spawn一樣簡(jiǎn)單。基本上要掌握Go語(yǔ)言,以Goroutine和channel為核心的內(nèi)存模型是必須要懂的。不過(guò)請(qǐng)放心,真的非常簡(jiǎn)單。
7. 更多現(xiàn)代的特性
和C比較,Go語(yǔ)言完全就是一門現(xiàn)代化語(yǔ)言,原生支持的Unicode, garbage collection, Closures(是的,和functional programming language類似), function是first class object,等等等等。
看到這里,你可能會(huì)發(fā)現(xiàn),我用了很多輕易,簡(jiǎn)單,快速之類的形容詞來(lái)形容Go語(yǔ)言的特點(diǎn)。我想說(shuō)的是,一點(diǎn)都不夸張,連Go語(yǔ)言的入門學(xué)習(xí)到提高,都比別的語(yǔ)言門檻低太多太多。在大部分人都有C的背景的時(shí)代,對(duì)于Go語(yǔ)言,從入門到能夠上手做項(xiàng)目,最多不過(guò)半個(gè)月。Go語(yǔ)言給人的感覺(jué)就是太直接了,什么都直接,讀源代碼直接,寫自己的代碼也直接。
前言:go語(yǔ)言函數(shù)參數(shù)為值拷貝(指針參數(shù)為指針拷貝)。
在go語(yǔ)言中,函數(shù)也作為一種數(shù)據(jù)類型,所以函數(shù)也可以作為函數(shù)的參數(shù)來(lái)使用。
其中slice是為地址數(shù)組指針的拷貝??,持續(xù)更新中 ....
按值傳遞函數(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ù)之外。
當(dāng)前標(biāo)題:go語(yǔ)言多參數(shù) go語(yǔ)言參數(shù)傳遞
文章地址:http://www.chinadenli.net/article0/docdjoo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供營(yíng)銷型網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)公司、網(wǎng)站收錄、云服務(wù)器、網(wǎng)站策劃、定制開發(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)