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

go語言中op函數(shù) go 定義函數(shù)

GO語言(十五):泛型入門(下)-

在本節(jié)中,您將添加通用函數(shù)調(diào)用的修改版本,進(jìn)行小的更改以簡化調(diào)用代碼。您將刪除在這種情況下不需要的類型參數(shù)。

創(chuàng)新互聯(lián)主要從事成都網(wǎng)站制作、成都做網(wǎng)站、外貿(mào)營銷網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)李滄,10年網(wǎng)站建設(shè)經(jīng)驗,價格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):13518219792

當(dāng) Go 編譯器可以推斷您要使用的類型時,您可以在調(diào)用代碼中省略類型參數(shù)。編譯器從函數(shù)參數(shù)的類型推斷類型參數(shù)。

請注意,這并不總是可能的。例如,如果您需要調(diào)用沒有參數(shù)的泛型函數(shù),則需要在函數(shù)調(diào)用中包含類型參數(shù)。

在 main.go 中,在您已有的代碼下方,粘貼以下代碼。

在此代碼中:

(1)調(diào)用泛型函數(shù),省略類型參數(shù)。

從包含 main.go 的目錄中的命令行,運(yùn)行代碼。

接下來,您將通過將整數(shù)和浮點(diǎn)數(shù)的并集捕獲到您可以重用的類型約束(例如從其他代碼中)來進(jìn)一步簡化函數(shù)。

正如您將在本節(jié)中看到的,約束接口也可以引用特定類型。

1、編寫代碼

在此代碼中:

b.在您已有的函數(shù)下方,粘貼以下通用 SumNumbers函數(shù)。

在此代碼中:

c.在 main.go 中,在您已有的代碼下方,粘貼以下代碼。

在此代碼中:

(1)調(diào)用SumNumbers打印每個map的總和。

與上一節(jié)一樣,在調(diào)用泛型函數(shù)時省略了類型參數(shù)(方括號中的類型名稱)。Go 編譯器可以從其他參數(shù)推斷類型參數(shù)。

從包含 main.go 的目錄中的命令行,運(yùn)行代碼。

做得很好!您剛剛學(xué)習(xí)了 Go 中的泛型。

如何看待go語言泛型的最新設(shè)計?

Go 由于不支持泛型而臭名昭著,但最近,泛型已接近成為現(xiàn)實(shí)。Go 團(tuán)隊實(shí)施了一個看起來比較穩(wěn)定的設(shè)計草案,并且正以源到源翻譯器原型的形式獲得關(guān)注。本文講述的是泛型的最新設(shè)計,以及如何自己嘗試泛型。

例子

FIFO Stack

假設(shè)你要創(chuàng)建一個先進(jìn)先出堆棧。沒有泛型,你可能會這樣實(shí)現(xiàn):

type?Stack?[]interface{}func?(s?Stack)?Peek()?interface{}?{

return?s[len(s)-1]

}

func?(s?*Stack)?Pop()?{

*s?=?(*s)[:

len(*s)-1]

}

func?(s?*Stack)?Push(value?interface{})?{

*s?=?

append(*s,?value)

}

但是,這里存在一個問題:每當(dāng)你 Peek 項時,都必須使用類型斷言將其從 interface{} 轉(zhuǎn)換為你需要的類型。如果你的堆棧是 *MyObject 的堆棧,則意味著很多 s.Peek().(*MyObject)這樣的代碼。這不僅讓人眼花繚亂,而且還可能引發(fā)錯誤。比如忘記 * 怎么辦?或者如果您輸入錯誤的類型怎么辦?s.Push(MyObject{})` 可以順利編譯,而且你可能不會發(fā)現(xiàn)到自己的錯誤,直到它影響到你的整個服務(wù)為止。

通常,使用 interface{} 是相對危險的。使用更多受限制的類型總是更安全,因為可以在編譯時而不是運(yùn)行時發(fā)現(xiàn)問題。

泛型通過允許類型具有類型參數(shù)來解決此問題:

type?Stack(type?T)?[]Tfunc?(s?Stack(T))?Peek()?T?{

return?s[len(s)-1]

}

func?(s?*Stack(T))?Pop()?{

*s?=?(*s)[:

len(*s)-1]

}

func?(s?*Stack(T))?Push(value?T)?{

*s?=?

append(*s,?value)

}

這會向 Stack 添加一個類型參數(shù),從而完全不需要 interface{}?,F(xiàn)在,當(dāng)你使用 Peek() 時,返回的值已經(jīng)是原始類型,并且沒有機(jī)會返回錯誤的值類型。這種方式更安全,更容易使用。(譯注:就是看起來更丑陋,^-^)

此外,泛型代碼通常更易于編譯器優(yōu)化,從而獲得更好的性能(以二進(jìn)制大小為代價)。如果我們對上面的非泛型代碼和泛型代碼進(jìn)行基準(zhǔn)測試,我們可以看到區(qū)別:

type?MyObject?struct?{

X?

int

}

var?sink?MyObjectfunc?BenchmarkGo1(b?*testing.B)?{

for?i?:=?0;?i??b.N;?i++?{

var?s?Stack

s.Push(MyObject{})

s.Push(MyObject{})

s.Pop()

sink?=?s.Peek().(MyObject)

}

}

func?BenchmarkGo2(b?*testing.B)?{

for?i?:=?0;?i??b.N;?i++?{

var?s?Stack(MyObject)

s.Push(MyObject{})

s.Push(MyObject{})

s.Pop()

sink?=?s.Peek()

}

}

結(jié)果:

BenchmarkGo1BenchmarkGo1-16?????12837528?????????87.0?ns/op???????48?B/op????????2?allocs/opBenchmarkGo2BenchmarkGo2-16?????28406479?????????41.9?ns/op???????24?B/op????????2?allocs/op

在這種情況下,我們分配更少的內(nèi)存,同時泛型的速度是非泛型的兩倍。

合約(Contracts)

上面的堆棧示例適用于任何類型。但是,在許多情況下,你需要編寫僅適用于具有某些特征的類型的代碼。例如,你可能希望堆棧要求類型實(shí)現(xiàn) String() 函數(shù)

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

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

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

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

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

一個簡單的示例:

輸出為:

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

返回:通過用 return 來進(jìn)行返回

輸出為:

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

對例子的說明:

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

引用傳遞:相當(dāng)于按指針傳遞,可以同時改變原來的值,并且消耗的內(nèi)存會更少,只有4或8個字節(jié)的消耗

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

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

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

輸出為:

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

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

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

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

輸出為

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

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

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

為什么我不會舍棄Python投奔Go語言

在Go語言中,規(guī)定的方式是,函數(shù)返回錯誤信息。這沒什么。如果一個文件并不存在,op.Open函數(shù)會返回一個錯誤信息。這沒什么。如果你向你一個中斷了的網(wǎng)絡(luò)連接里寫數(shù)據(jù),net.Conn里的Write方法會返回一個錯誤。這沒什么。這種狀況在這種程序中是可以預(yù)料到的。這種操作就是容易失敗,你知道程序會如何運(yùn)行,因為API的設(shè)計者通過內(nèi)置了一種錯誤情況的結(jié)果而讓這一切顯得很清楚。

從另一方面講,有些操作基本上不會出錯,所處的環(huán)境根本不可能給你提示錯誤信息,不可能控制錯誤。這才是讓人痛苦的地方。典型的例子;一個程序執(zhí)行

x[j],j值超出數(shù)組邊界,這才痛苦。像這樣預(yù)料之外的麻煩在程序中是一個嚴(yán)重的bug,一般會弄死程序的運(yùn)行。不幸的是,由于這種情況的存在,我們很難寫出健壯的,具有自我防御的服務(wù)器——例如,可以應(yīng)付偶然出現(xiàn)的有bug的HTTP請求處理器時,不影響其他服務(wù)的啟動和運(yùn)行。為解決這個問題,我們引入了恢復(fù)機(jī)制,它能讓一個go例程從錯誤中恢復(fù),服務(wù)余下設(shè)定的調(diào)用。然而,代價是,至少會丟失一個調(diào)用。這是特意而為之的。引用郵件中的原話:“這種設(shè)計不同于常見的異??刂平Y(jié)構(gòu),這是一個認(rèn)真思考后的決定。我們不希望像java語言里那樣把錯誤和異?;鞛橐徽?。”

我剛開始提到的那篇文章里問“為什么數(shù)組越界造成的麻煩會比錯誤的網(wǎng)址或斷掉的網(wǎng)絡(luò)引出的問題要大?”答案是,我們沒有一種內(nèi)聯(lián)并行的方法來報告在執(zhí)行x[j]期間產(chǎn)生的錯誤,但我們有內(nèi)聯(lián)并行的方法報告由錯誤網(wǎng)址或網(wǎng)絡(luò)問題造成的錯誤。

使用Go語言中的錯誤返回模式的規(guī)則很簡單:如果你的函數(shù)在某種情況下很容易出錯,那它就應(yīng)該返回錯誤。當(dāng)我調(diào)用其它的程序庫時,如果它是這樣寫的,那我不必?fù)?dān)心那些錯誤的產(chǎn)生,除非有真正異常的狀況,我根本沒有想到需要處理它們。

有一個你需要記在心里的事情是,Go語言是為大型軟件設(shè)計的。我們都喜歡程序簡潔清晰,但對于一個由很多程序員一起開發(fā)的大型軟件,維護(hù)成本的增加很難讓程序簡潔。異常捕捉模式的錯誤處理方式的一個很有吸引力的特點(diǎn)是,它非常適合小程序。但對于大型程序庫,如果對于一些普通操作,你都需要考慮每行代碼是否會拋出異常、是否有必要捕捉處理,這對于開發(fā)效率和程序員的時間來說都是非常嚴(yán)重的拖累。我自己做開發(fā)大型Python軟件時感受到了這個問題。

Go語言的返回錯誤方式,不可否認(rèn),對于調(diào)用者不是很方便,但這樣做會讓程序中可能會出錯的地方顯的很明顯。對于小程序來說,你可能只想打印出錯誤,退出程序。對于一些很精密的程序,根據(jù)異常的不同,來源的不同,程序會做出不同的反應(yīng),這很常見,這種情況中,try

+

catch的方式相對于錯誤返回模式顯得冗長。當(dāng)然,Python里的一個10行的代碼放到Go語言里很可能會更冗長。畢竟,Go語言主要不是針對10行規(guī)模的程序的。

就是要說明這一點(diǎn):Go語言程序員認(rèn)為,把error作為一種內(nèi)置的類型是非常重要的。

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

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

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

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

語法解析:

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

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

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

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

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

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

Go語言文件操作

本文主要介紹了Go語言中文件讀寫的相關(guān)操作。

文件是什么?

計算機(jī)中的文件是存儲在外部介質(zhì)(通常是磁盤)上的數(shù)據(jù)集合,文件分為文本文件和二進(jìn)制文件。

os.Open() 函數(shù)能夠打開一個文件,返回一個 *File 和一個 err 。對得到的文件實(shí)例調(diào)用 close() 方法能夠關(guān)閉文件。

為了防止文件忘記關(guān)閉,我們通常使用defer注冊文件關(guān)閉語句。

Read方法定義如下:

它接收一個字節(jié)切片,返回讀取的字節(jié)數(shù)和可能的具體錯誤,讀到文件末尾時會返回 0 和 io.EOF 。 舉個例子:

使用for循環(huán)讀取文件中的所有數(shù)據(jù)。

bufio是在file的基礎(chǔ)上封裝了一層API,支持更多的功能。

io/ioutil 包的 ReadFile 方法能夠讀取完整的文件,只需要將文件名作為參數(shù)傳入。

os.OpenFile() 函數(shù)能夠以指定模式打開文件,從而實(shí)現(xiàn)文件寫入相關(guān)功能。

其中:

name :要打開的文件名 flag :打開文件的模式。 模式有以下幾種:

perm :文件權(quán)限,一個八進(jìn)制數(shù)。r(讀)04,w(寫)02,x(執(zhí)行)01。

分享文章:go語言中op函數(shù) go 定義函數(shù)
標(biāo)題網(wǎng)址:http://chinadenli.net/article24/hpisje.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、全網(wǎng)營銷推廣商城網(wǎng)站、定制開發(fā)、企業(yè)網(wǎng)站制作、品牌網(wǎng)站建設(shè)

廣告

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

h5響應(yīng)式網(wǎng)站建設(shè)