版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第一起聊聊Go語言中的語法糖的使用目錄前言進(jìn)入正題可變長參數(shù)聲明不定長數(shù)組...操作符切片循環(huán)忽略變量、字段或者導(dǎo)包短變量聲明另類的返回值總結(jié)
前言
由于工作變動,我現(xiàn)在已經(jīng)開始使用Golang了。用了一段時間之后,我發(fā)現(xiàn)Golang(后面簡稱Go)中的語法糖還蠻多的,有些語法糖還讓會讓人很懵逼。那么接下來,讓我以一個曾經(jīng)的JavaCURDboy,來說一說Go中的語法糖。
進(jìn)入正題
至于什么是語法糖,名詞解釋我就不解釋了,老司機(jī)自然是懂,新手司機(jī)想了解的可以去百度問一下。閑話少說我們直接開講。
可變長參數(shù)
Go語言允許一個函數(shù)把任意數(shù)量的值作為參數(shù),Go語言內(nèi)置了...操作符,在函數(shù)的最后一個形參才能使用...操作符,使用它必須注意如下事項
可變長參數(shù)必須在函數(shù)列表的最后一個;把可變長參數(shù)當(dāng)切片來解析,可變長參數(shù)沒有沒有值時就是個空切片可變長參數(shù)的類型必須相同
functest(aint,b...int){
fmt.Println("a=",a,",b=",b,",b的類型=",reflect.TypeOf(b))
return
}
輸出結(jié)果如下:
a=1,b=[],b的類型=[]int
為啥說可變長參數(shù)的值用切片來解析,而不是數(shù)組。為什么是這樣有興趣的朋友可以思考一下
可變長參數(shù)這個語法糖,不是Go獨有的,Java中也有,不同的是Java是通過數(shù)組實現(xiàn)此語法糖的。從實際開發(fā)經(jīng)驗來看,這個語法糖我在使用Java開發(fā)時,貌似一次都沒有用過,用Go開發(fā)的時候我用的次數(shù)還挺多的,具體在什么地方用,后面有機(jī)會我再說說它是如何使用的。
聲明不定長數(shù)組
我么都知道數(shù)組長度是固定的,所以在聲明數(shù)組的時候都要指定長度,Go里提供了一種偷懶的聲明方式,即使用...操作符聲明數(shù)組時,我們只管填充元素值,其他的由Go編譯器來處理。
//Go的實現(xiàn):數(shù)組長度是4,等同于a:=[4]{1,2,3,4}
a:=[...]int{1,2,3,4}
這個Java中有實現(xiàn),而且感覺比Go的還簡單,具體如下:
//Java的實現(xiàn):數(shù)組長度是4
int[]x={1,2,3,4};
在我短暫的職業(yè)生涯中,無論我使用Java還是Go開發(fā)的時候,數(shù)組使用的頻率都是比較少的。
ps我發(fā)現(xiàn)這個...好像也算是一個語法糖
...操作符
...這個叫啥名字,我也沒有找到官方的叫法。但是我發(fā)現(xiàn)在Go實際的開發(fā)過程中用的地方還蠻多的。
函數(shù)的參數(shù)聲明。如:funcfuncName(nums...int),在函數(shù)的方法體內(nèi),nums作為一個切片[]int來使用,這個上面已經(jīng)提到了。傳參時列表打散。如:params=[]int{1,2,3},調(diào)用某個有三個參數(shù)的方法funcThreeParamFunc(a,b,cint)時可以ThreeParamFunc(params...)。三個點...在JavaScript中的名叫擴(kuò)展運算符,是在ES6中新增加的內(nèi)容,它可以在函數(shù)調(diào)用/數(shù)組構(gòu)造時,將數(shù)組表達(dá)式或者string在語法層面展開;還可以在構(gòu)造字面量對象時將對象表達(dá)式按照key-value的方式展開,例如:
//數(shù)組
varnumber=[1,2,3,4,5,6]
console.log(...number)//123456
varman={name:'蔡',height:180}
console.log({...man})/{name:'蔡',height:180}
所以我覺得在Go里面在這種情況下,我們也可以稱...為擴(kuò)展運算符。
聲明不定長數(shù)組。如果元素指定,那么可以不必顯式聲明數(shù)組長度,可以根據(jù)元素個數(shù)推斷,如:arr:=[...]int{1,2,3},這個上面已經(jīng)提到了。在go命令行中,被當(dāng)做包列表的通配符。如:$gotest./...這條命令會執(zhí)行當(dāng)前目錄及子目錄下的所有包測試文件。
切片循環(huán)
在Go中提供了forrange語法來快速迭代對象。數(shù)組、切片、字符串、map、channel等等類型都可以使用這種方式進(jìn)行遍歷,總結(jié)起來有以下幾種形式:
只遍歷不關(guān)心數(shù)據(jù),適用于切片、數(shù)組、字符串、map、channel
forrangeT{}
遍歷獲取索引或數(shù)組,切片,數(shù)組、字符串就是索引,map就是key,channel就是數(shù)據(jù)
forkey:=rangeT{}
遍歷獲取索引和數(shù)據(jù),適用于切片、數(shù)組、字符串,第一個參數(shù)就是索引,第二個參數(shù)就是對應(yīng)的元素值,map第一個參數(shù)就是key,第二個參數(shù)就是對應(yīng)的值;
forkey,value:=rangeT{}
其實在實際開發(fā)中,我們會大概率會遇到遍歷map時,只關(guān)心map中的數(shù)據(jù),不關(guān)心key的情況。這個時候我們就是使用最后一種方式,這個key聲明了但是沒有用,Go這個時候就會提示一個語法錯誤key沒有使用,那我們只好使用Go的另外一個語法糖_忽略標(biāo)識符(就是一個下劃線)忽略key,具體如下:
for_,value:=rangeT{}
在Java中循環(huán)map的方式有很多種,但有一點就是,開發(fā)者可以使用keySet()、values()選擇遍歷key或者value。
//打印鍵集合
for(Stringkey:map.keySet()){
System.out.println(key);
//打印值集合
for(Stringvalue:map.values()){
System.out.println(value);
另外注意一點,在Go中如果一個切片是nil的時候,我們對他進(jìn)行遍歷或者append操作的時候,是不會出現(xiàn)報錯的,這一點很不錯,省的像用Java時遍歷對象需要判斷他是否為null。
funcmain(){
temp:=make([]int,0)
temp=nil
for_,val:=rangetemp{
fmt.Println("val=",val)
temp=append(temp,1)
fmt.Println("val=",temp)
上述操作都是不會報錯的,大家放心食用!
忽略變量、字段或者導(dǎo)包
這個前面提到了一點,使用_忽略變量。在Go中還有其他幾種常見的場景,具體如下:
json序列化忽略某個字段我們都會對struct做序列化操作,但有些時候我們想要json里面的某些字段不參加序列化,Go語言的結(jié)構(gòu)體提供標(biāo)簽功能,在結(jié)構(gòu)體標(biāo)簽中使用-操作符就可以對不需要序列化的字段做特殊處理,使用如下:
typeItemstruct{
Iduint32`json:"id"`
Namestring`json:"name"`
Passwordstring`json:"-"`
這個Java中也有類似的實現(xiàn),只要在Java類的屬性前加上transient關(guān)鍵字修飾即可。當(dāng)然在將Java類序列化成json時可以使用對應(yīng)的注解,這里我就不細(xì)說了。
json序列化忽略空值字段使用json.Marshal進(jìn)行序列化時不會忽略struct中的空值(這里說的空值包含空字符串和nil),默認(rèn)輸出字段的類型零值(string類型零值是,指針類型的零值是nil),如果我們想在序列化時忽略掉這些沒有值的字段時,可以在結(jié)構(gòu)體標(biāo)簽中中添加omitemptytag。
typeItemstruct{
Iduint32`json:"id"`
Namestring`json:"name,omitempty"`
Passwordstring`json:"-"`
這里說一下,在Java里類型分為基本類型和包裝類型,Java類初始化的時候?qū)傩詾榛绢愋腿绻麤]有賦予初始值,默認(rèn)值是0。包裝類型聲明時沒有賦值的話的初始值為null。Go中初始化時沒有賦值的變量的默認(rèn)值如下:
布爾類型的默認(rèn)為false數(shù)值類型的默認(rèn)為0字符串類型的默認(rèn)為空字符串指針類型、函數(shù)、接口、切片、通道和map默認(rèn)值為nil
這樣看來Java和Go這個場景下處理方式,有相似和不同之處,大家開發(fā)的時候要注意,由Java轉(zhuǎn)Go的同學(xué)開發(fā)時,千萬別搞混了。
短變量聲明
在強(qiáng)類型語言中,聲明一個變量都需要指定變量的類型??赡苷Z言的開發(fā)者覺得這樣做對開發(fā)者不太友好,就搞了個變量聲明不用指定類型的語法糖,其實這個玩意說起來就是類型推導(dǎo)(Java8之后的版本貌似已經(jīng)有了),開發(fā)者只管定義變量,類型由語言編譯器來處理。
a:=10
varaint=10
b:=fucName()
怎么說呢這樣有好處也有壞處,定義變量的人省事了,使用變量的人可能就懵逼了。就像這種場景b:=fucName(),這個變量b是啥類型,這個時候你只能點擊函數(shù)內(nèi),看函數(shù)的返回值類型是啥,才能確定變量b是啥類型。
我之前寫過幾年的PHP,后來轉(zhuǎn)了Java,再到現(xiàn)在寫Go。我發(fā)現(xiàn)各種開發(fā)語言都在進(jìn)步,而且還相互模仿,PHP中函數(shù)之前不用指定形參類型,PHP8中好像可以指定形參類型了??傊褪菑?qiáng)弱類型的語言在相互靠攏。
另類的返回值
在Go語言中,允許您使用return語句從一個函數(shù)返回多個值。換句話說,在函數(shù)中,單個return語句可以返回多個值。返回值的類型類似于參數(shù)列表中定義的參數(shù)的類型。
funcfunc1(astring,bint)int{
fmt.Println("func1------------")
fmt.Println("a1=",a)
fmt.Println("b1=",b)
c:=100
returnc
}
可以這樣寫:返回多個返回值,形參命名
funcfunc2(astring,bint)(int,int){
fmt.Println("func2------------")
fmt.Println("a2=",a)
fmt.Println("b2=",b)
return12,33
可以這樣寫:返回多個返回值,形參匿名
funcfunc3(astring,bint)(int,int){
fmt.Println("func3------------")
fmt.Println("a2=",a)
fmt.Println("b2=",b)
return12,33
如果一個函數(shù)要返回多個值,在Java中可以使用定義一個新的類來承載返回值,或者偷個懶使用map來接也是可以的。go支持多個返回值就我個人來說還是支持的。其實說到這里,多個返回值的各種形式都能理解。直到有一天我在翻看gorm的Open方法源碼發(fā)現(xiàn)了奇怪的地方,代碼位置信息:gorm.io/gorm@v1.23.4/gorm.go:116,節(jié)選部分代碼如下:
funcOpen(dialectorDialector,opts...Option)(db*DB,errerror){
config:=Config{}
ifd,ok:=dialector.(interface{Apply(*Config)error});ok{
iferr=d.Apply(config);err!=nil{
return
#省略此處無用代碼
db=DB{Config:config,clone:1}
db.callbacks=initializeCallbacks(db)
#省略此處無用代碼
preparedStmt:=PreparedStmtDB{
ConnPool:db.ConnPool,
Stmts:map[string]Stmt{},
Mux:sync.RWMutex{},
PreparedSQL:make([]string,0,100),
db.cacheStore.Store(preparedStmtDBKey,preparedStmt)
#省略此處無用代碼
db.Statement=Statement{
DB:db,
ConnPool:db.ConnPool,
Context:context.Background(),
Clauses:map[string]clause.Clause{},
#省略此處無用代碼
return
}
這就是文章開頭提到的讓人懵逼的語法糖,我當(dāng)時看到這段代碼時,我心中暗想這個是什么TM操作,竟然這樣也行,這樣竟然沒有報錯我來點出其中的問題,就是return關(guān)鍵字
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024-2025學(xué)年山東省菏澤市高二下學(xué)期期中考試歷史試題(A)(解析版)
- 2024-2025學(xué)年江蘇省鹽城市高二下學(xué)期期終考試歷史試題(解析版)
- 2026年生物與醫(yī)學(xué)前沿科技知識競賽題集
- 2026年計算機(jī)應(yīng)用基礎(chǔ)初級水平測試題
- 2026年心理學(xué)入門認(rèn)知心理學(xué)與社會心理學(xué)試題庫
- 2026年城市規(guī)劃領(lǐng)域?qū)I(yè)技術(shù)人員考試練習(xí)題集
- 2026年文化常識與歷史知識綜合測試題
- 2026年高考化學(xué)模擬試題及答案解析
- 2026年寫作技巧基礎(chǔ)訓(xùn)練初級自測模擬題
- 2026年房地產(chǎn)銷售經(jīng)理人才選拔模擬測試
- 頸內(nèi)靜脈血栓的護(hù)理
- 操作工技能等級評級方案
- 國家職業(yè)技術(shù)技能標(biāo)準(zhǔn) 5-05-02-01 農(nóng)作物植保員 人社廳發(fā)202021號
- 購房委托書范文
- 素描第2版(藝術(shù)設(shè)計相關(guān)專業(yè))全套教學(xué)課件
- 新生兒先天性腎上腺皮質(zhì)增生癥
- 中國傳統(tǒng)木雕工藝美術(shù)的繼承與發(fā)展-以平遙木雕神像傳統(tǒng)技藝為例
- (完整版)四宮格數(shù)獨題目204道(可直接打印)及空表(一年級數(shù)獨題練習(xí))
- DB32/T+4539-2023+淡水生物環(huán)境DNA監(jiān)測技術(shù)方法
- 火電廠鍋爐運行與維護(hù)
- CTM系列產(chǎn)品使用手冊
評論
0/150
提交評論