




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第細(xì)說Go語言中空結(jié)構(gòu)體的奇妙用途目錄1.空結(jié)構(gòu)體的定義和初始化2.空結(jié)構(gòu)體的大小和內(nèi)存占用3.空結(jié)構(gòu)體作為占位符4.空結(jié)構(gòu)體作為通道元素5.空結(jié)構(gòu)體作為map的占位符6.空結(jié)構(gòu)體作為方法接收器7.空結(jié)構(gòu)體作為接口實(shí)現(xiàn)8.空結(jié)構(gòu)體作為信號(hào)量9.總結(jié)在Go語言中,我們可以定義空結(jié)構(gòu)體(emptystruct),即沒有任何成員變量的結(jié)構(gòu)體,使用關(guān)鍵字struct{}來表示。這種結(jié)構(gòu)體似乎沒有任何用處,但實(shí)際上它在Go語言中的應(yīng)用非常廣泛,本文將從多個(gè)方面介紹空結(jié)構(gòu)體的使用,讓大家更好地理解它的作用。
1.空結(jié)構(gòu)體的定義和初始化
空結(jié)構(gòu)體是指不包含任何字段的結(jié)構(gòu)體。在Golang中,可以使用struct{}來定義一個(gè)空結(jié)構(gòu)體。下面是一個(gè)簡單的示例:
packagemain
import"fmt"
funcmain(){
varsstruct{}
fmt.Printf("%#v\n",s)//輸出:struct{}{}
}
在這個(gè)示例中,我們定義了一個(gè)名為s的變量,并將其初始化為一個(gè)空結(jié)構(gòu)體。然后我們使用fmt.Printf將這個(gè)空結(jié)構(gòu)體打印出來。注意,在打印時(shí)使用了%#v占位符,這個(gè)占位符可以將變量以Go語法格式輸出。
輸出結(jié)果是struct{}{},這表示s是一個(gè)空結(jié)構(gòu)體,不包含任何字段。需要注意的是,空結(jié)構(gòu)體變量實(shí)際上不占用任何內(nèi)存空間,也就是說,它的大小是0字節(jié)。
2.空結(jié)構(gòu)體的大小和內(nèi)存占用
正如上面提到的,空結(jié)構(gòu)體的大小是0字節(jié)。這意味著它不占用任何內(nèi)存空間。這一點(diǎn)可以通過使用unsafe.Sizeof函數(shù)來驗(yàn)證:
packagemain
import(
"fmt"
"unsafe"
funcmain(){
varsstruct{}
fmt.Printf("Sizeofstruct{}:%v\n",unsafe.Sizeof(s))//輸出:Sizeofstruct{}:0
}
在這個(gè)示例中,我們使用unsafe.Sizeof函數(shù)獲取s的大小,并將結(jié)果打印出來。由于s是一個(gè)空結(jié)構(gòu)體,它的大小為0。
需要注意的是,盡管空結(jié)構(gòu)體的大小為0,但它并不意味著它不能被作為函數(shù)參數(shù)或返回值傳遞。因?yàn)樵贕o中,每個(gè)類型都有自己的類型信息,可以用于類型檢查和轉(zhuǎn)換。因此,即使是空結(jié)構(gòu)體,在類型系統(tǒng)中也有它自己的位置和作用。
3.空結(jié)構(gòu)體作為占位符
空結(jié)構(gòu)體最常見的用途是作為占位符。在函數(shù)或方法簽名中,如果沒有任何參數(shù)或返回值,那么可以使用空結(jié)構(gòu)體來標(biāo)識(shí)這個(gè)函數(shù)或方法。下面是一個(gè)簡單的示例:
packagemain
import"fmt"
funcdoSomething()struct{}{
fmt.Println("Doingsomething")
returnstruct{}{}
funcmain(){
doSomething()
}
在這個(gè)示例中,我們定義了一個(gè)名為doSomething的函數(shù),它不接受任何參數(shù),也不返回任何值。我們可以使用空結(jié)構(gòu)體來標(biāo)識(shí)它的返回值。在doSomething函數(shù)的實(shí)現(xiàn)中,我們只是打印了一條消息,然后返回一個(gè)空結(jié)構(gòu)體。
在main函數(shù)中,我們調(diào)用doSomething函數(shù)。由于它沒有返回任何值,所以我們不需要將其結(jié)果存儲(chǔ)在變量中。
需要注意的是,在這個(gè)示例中,我們將返回值的類型顯式指定為struct{}。這是因?yàn)槿绻恢付ǚ祷刂档念愋?,那么Go編譯器會(huì)將它默認(rèn)解析為interface{}類型。在這種情況下,每次調(diào)用doSomething函數(shù)都會(huì)分配一個(gè)新的空接口對(duì)象,這可能會(huì)帶來性能問題。
4.空結(jié)構(gòu)體作為通道元素
空結(jié)構(gòu)體還可以用作通道的元素類型。在Go中,通道是一種用于在協(xié)程之間進(jìn)行通信和同步的機(jī)制。使用通道時(shí),我們需要指定通道中元素的類型。
如果我們不需要在通道中傳輸任何值,那么可以使用空結(jié)構(gòu)體作為元素類型。下面是一個(gè)簡單的示例:
packagemain
import"fmt"
funcmain(){
c:=make(chanstruct{})
gofunc(){
fmt.Println("Goroutineisrunning")
c-struct{}{}
fmt.Println("Goroutineisdone")
}
在這個(gè)示例中,我們創(chuàng)建了一個(gè)名為c的通道,并將其元素類型指定為struct{}。然后,我們?cè)谝粋€(gè)新的協(xié)程中運(yùn)行一些代碼,并在協(xié)程中向通道中發(fā)送一個(gè)空結(jié)構(gòu)體。在main函數(shù)中,我們從通道中接收一個(gè)元素,這里實(shí)際上是在等待協(xié)程的結(jié)束。一旦我們接收到了一個(gè)元素,我們就會(huì)打印出Goroutineisdone。
需要注意的是,在這個(gè)示例中,我們并沒有向通道中發(fā)送任何有用的數(shù)據(jù)。相反,我們只是使用通道來同步協(xié)程之間的執(zhí)行。這種方法對(duì)于實(shí)現(xiàn)復(fù)雜的并發(fā)模型非常有用,因?yàn)樗梢员苊馐褂蔑@式的互斥量或信號(hào)量來實(shí)現(xiàn)同步和通信。
5.空結(jié)構(gòu)體作為map的占位符
在Go中,map是一種用于存儲(chǔ)鍵值對(duì)的數(shù)據(jù)結(jié)構(gòu)。如果我們只需要一個(gè)鍵集合,而不需要存儲(chǔ)任何值,那么可以使用空結(jié)構(gòu)體作為map的值類型。下面是一個(gè)簡單的示例:
packagemain
import"fmt"
funcmain(){
m:=make(map[string]struct{})
m["key1"]=struct{}{}
m["key2"]=struct{}{}
m["key3"]=struct{}{}
fmt.Println(len(m))//輸出:3
}
在這個(gè)示例中,我們創(chuàng)建了一個(gè)名為m的map,并將其值類型指定為struct{}。然后,我們向map中添加了三個(gè)鍵,它們的值都是空結(jié)構(gòu)體。最后,我們打印了map的長度,結(jié)果為3。
需要注意的是,在這個(gè)示例中,我們并沒有使用空結(jié)構(gòu)體的任何其他特性。我們只是使用它作為map的值類型,因?yàn)槲覀儾恍枰趍ap中存儲(chǔ)任何值。
6.空結(jié)構(gòu)體作為方法接收器
在Go中,方法是一種將函數(shù)與特定類型相關(guān)聯(lián)的機(jī)制。如果我們不需要訪問方法中的任何接收器字段,那么可以使用空結(jié)構(gòu)體作為接收器類型。下面是一個(gè)簡單的示例:
packagemain
import"fmt"
typeMyStructstruct{}
func(mMyStruct)DoSomething(){
fmt.Println("Methodiscalled")
funcmain(){
s:=MyStruct{}
s.DoSomething()
}
在這個(gè)示例中,我們創(chuàng)建了一個(gè)名為MyStruct的結(jié)構(gòu)體,并為其定義了一個(gè)方法DoSomething。在這個(gè)方法中,我們只是打印一條消息。
在main函數(shù)中,我們創(chuàng)建了一個(gè)MyStruct實(shí)例s,然后調(diào)用了它的DoSomething方法。由于我們不需要在方法中訪問接收器的任何字段,所以我們可以使用空結(jié)構(gòu)體作為接收器類型。
需要注意的是,即使我們?cè)诜椒ㄖ惺褂每战Y(jié)構(gòu)體作為接收器類型,我們?nèi)匀豢梢詫⑵渌麉?shù)傳遞給該方法。例如,我們可以像下面這樣修改DoSomething方法:
func(mMyStruct)DoSomething(xint,ystring){
fmt.Println("Methodiscalledwith",x,y)
}
在這個(gè)示例中,我們向DoSomething方法添加了兩個(gè)參數(shù)。然而,我們?nèi)匀豢梢允褂每战Y(jié)構(gòu)體作為接收器類型。
7.空結(jié)構(gòu)體作為接口實(shí)現(xiàn)
在Go中,接口是一種定義對(duì)象行為的機(jī)制。如果我們不需要實(shí)現(xiàn)接口的任何方法,那么可以使用空結(jié)構(gòu)體作為實(shí)現(xiàn)。下面是一個(gè)簡單的示例:
packagemain
import"fmt"
typeMyInterfaceinterface{
DoSomething()
typeMyStructstruct{}
func(mMyStruct)DoSomething(){
fmt.Println("Methodiscalled")
funcmain(){
s:=MyStruct{}
variMyInterface=s
i.DoSomething()
}
在這個(gè)示例中,我們定義了一個(gè)名為MyInterface的接口,并為其定義了一個(gè)方法DoSomething。我們還定義了一個(gè)名為MyStruct的結(jié)構(gòu)體,并為其實(shí)現(xiàn)了DoSomething方法。
在main函數(shù)中,我們創(chuàng)建了一個(gè)MyStruct實(shí)例s,然后將其分配給MyInterface類型的變量i。由于MyStruct實(shí)現(xiàn)了DoSomething方法,所以我們可以調(diào)用i.DoSomething方法,并打印出一條消息。
需要注意的是,在這個(gè)示例中,我們并沒有為接口實(shí)現(xiàn)添加任何特殊。我們只是使用空結(jié)構(gòu)體作為實(shí)現(xiàn),因?yàn)槲覀儾恍枰獙?shí)現(xiàn)接口的任何方法。
8.空結(jié)構(gòu)體作為信號(hào)量
在Go中,我們可以使用空結(jié)構(gòu)體作為信號(hào)量,以控制并發(fā)訪問。下面是一個(gè)簡單的示例:
packagemain
import(
"fmt"
"sync"
funcmain(){
varwgsync.WaitGroup
varmusync.Mutex
varsignalstruct{}
fori:=0;ii++{
wg.Add(1)
gofunc(idint){
mu.Lock()
defermu.Unlock()
fmt.Println("goroutine",id,"iswaiting")
wg.Wait()
fmt.Println("goroutine",id,"issignaled")
}(i)
fmt.Println("mainthreadissleeping")
fmt.Println("pressentertosignalallgoroutines")
fmt.Scanln()
closeCh:=make(chanstruct{})
gofunc(){
for{
select{
case-closeCh:
return
default:
mu.Lock()
signal=struct{}{}
mu.Unlock()
fmt.Println("allgoroutinesaresignaled")
close(closeCh)
wg.Wait()
fmt.Println("allgoroutinesaredone")
}
在這個(gè)示例中,我們創(chuàng)建了一個(gè)WaitGroup和一個(gè)Mutex,以便在多個(gè)goroutine之間同步。我們還定義了一個(gè)名為signal的空結(jié)構(gòu)體。
在for循環(huán)中,我們啟動(dòng)了5個(gè)goroutine。在每個(gè)goroutine中,我們獲取Mutex鎖,并打印一條等待消息。然后,我們使用WaitGroup等待所有g(shù)oroutine完成。
在main函數(shù)中,我們等待一段時(shí)間,然后向所有g(shù)oroutine發(fā)送信號(hào)。為了實(shí)現(xiàn)這一點(diǎn),我們創(chuàng)建了一個(gè)名為closeCh的信道,并在其中創(chuàng)建了一個(gè)無限循環(huán)。在每次循環(huán)中,我們檢查是否有closeCh信道收到了關(guān)閉信號(hào)。如果沒有,我們獲取Mutex鎖,并將signal變量設(shè)置為一個(gè)空結(jié)構(gòu)體。這樣,所有正在等待signal變量的goroutine都會(huì)被喚醒。
最后,我們等待所有g(shù)oroutine完成,并打印一條完成消息。
需要注意的是
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 姜黃素外泌體涂層生物可吸收支架制備及性能研究
- 江門臺(tái)山市汶村鎮(zhèn)招聘筆試真題2024
- 上海公務(wù)員行測(cè)(C類)真題及答案
- 2024年福建銀行招聘真題
- 浙江汽車職業(yè)技術(shù)學(xué)院《社會(huì)工作專業(yè)論文寫作》2023-2024學(xué)年第二學(xué)期期末試卷
- 麗江職業(yè)技術(shù)學(xué)院《微積分Ⅱ(一)》2023-2024學(xué)年第二學(xué)期期末試卷
- 廣東環(huán)境保護(hù)工程職業(yè)學(xué)院《室內(nèi)設(shè)計(jì)專題(軟裝設(shè)計(jì))》2023-2024學(xué)年第二學(xué)期期末試卷
- 鄭州軌道工程職業(yè)學(xué)院《理性素描訓(xùn)練》2023-2024學(xué)年第二學(xué)期期末試卷
- 遼寧工程職業(yè)學(xué)院《臨床研究與循證醫(yī)學(xué)研究方法及實(shí)踐》2023-2024學(xué)年第二學(xué)期期末試卷
- 河北農(nóng)業(yè)大學(xué)現(xiàn)代科技學(xué)院《生物反應(yīng)與分離綜合實(shí)驗(yàn)》2023-2024學(xué)年第二學(xué)期期末試卷
- 2025年政治經(jīng)濟(jì)學(xué)考試題及答案回顧
- 《知識(shí)產(chǎn)權(quán)法學(xué)》一萬字筆記
- 固體廢物堆肥處理技術(shù)課件
- 腦卒中的診斷與治療
- 中國古茶樹資源狀況白皮書2025
- 牙科技術(shù)入股合作協(xié)議書
- 2025甘肅省農(nóng)墾集團(tuán)限責(zé)任公司人才招聘524人易考易錯(cuò)模擬試題(共500題)試卷后附參考答案
- 溫泉水項(xiàng)目可行性分析報(bào)告(模板參考范文)
- 2024年海關(guān)總署在京直屬事業(yè)單位招聘筆試真題
- T/CCIAS 010-2023雞精調(diào)味料生產(chǎn)技術(shù)規(guī)范
- 2025安全生產(chǎn)月主題宣講課件十:主要負(fù)責(zé)人安全公開課
評(píng)論
0/150
提交評(píng)論