go語(yǔ)言中空結(jié)構(gòu)體的實(shí)現(xiàn)
本文主要介紹了go語(yǔ)言中空結(jié)構(gòu)體的實(shí)現(xiàn),具體如下:

空結(jié)構(gòu)體(struct{})
- 普通理解
在結(jié)構(gòu)體中,可以包裹一系列與對(duì)象相關(guān)的屬性,但若該對(duì)象沒有屬性呢?那它就是一個(gè)空結(jié)構(gòu)體。
空結(jié)構(gòu)體,和正常的結(jié)構(gòu)體一樣,可以接收方法函數(shù)。
type Lamp struct{}
func (l Lamp) On() {
println("On")
}
func (l Lamp) Off() {
println("Off")
}
- 空結(jié)構(gòu)體的妙用
空結(jié)構(gòu)體的表象特征,就是沒有任何屬性,而從更深層次的角度來說,空結(jié)構(gòu)體是一個(gè)不占用空間的對(duì)象。
使用 unsafe.Sizeof 可以輕易的驗(yàn)證這個(gè)結(jié)果
type Lamp struct{}
func main() {
lamp := Lamp{}
fmt.Print(unsafe.Sizeof(lamp))
}
// output: 0
基于這個(gè)特性,在一些特殊的場(chǎng)合之下,可以用做占位符使用,合理的使用空結(jié)構(gòu)體,會(huì)減小程序的內(nèi)存占用空間。
比如在使用信道(channel)控制并發(fā)時(shí),我們只是需要一個(gè)信號(hào),但并不需要傳遞值,這個(gè)時(shí)候,也可以使用 struct{} 代替。
func main() {
ch := make(chan struct{}, 1)
go func() {
<-ch
// do something
}()
ch <- struct{}{}
// ...
}
在 Go 語(yǔ)言中,使用空結(jié)構(gòu)體(struct{})作為通道(chan)的元素類型是一種常見的優(yōu)化手段。這種做法主要出于以下幾個(gè)原因:
節(jié)省內(nèi)存空結(jié)構(gòu)體
struct{}在 Go 中不占用任何內(nèi)存空間(大小為 0 字節(jié))。因此,當(dāng)你需要一個(gè)通道來傳遞信號(hào)或同步協(xié)程時(shí),使用空結(jié)構(gòu)體可以避免不必要的內(nèi)存開銷。信號(hào)傳遞在某些場(chǎng)景下,你并不需要通過通道傳遞具體的數(shù)據(jù),而只是需要一個(gè)簡(jiǎn)單的信號(hào)機(jī)制來通知其他協(xié)程某個(gè)事件已經(jīng)發(fā)生。例如,用于關(guān)閉多個(gè)工作協(xié)程、通知某個(gè)操作完成等。此時(shí),空結(jié)構(gòu)體作為通道的元素類型非常合適。
提高性能由于空結(jié)構(gòu)體不占用內(nèi)存,發(fā)送和接收空結(jié)構(gòu)體的操作通常比發(fā)送和接收復(fù)雜數(shù)據(jù)類型的通道更快。雖然這種差異在大多數(shù)情況下是微不足道的,但在高并發(fā)或高性能要求的場(chǎng)景下,這些細(xì)微的優(yōu)化可能會(huì)產(chǎn)生顯著的影響。
.關(guān)閉多個(gè)工作協(xié)程
package main
import (
"fmt"
"time"
)
func worker(id int, done chan struct{}) {
for {
select {
case <-done:
fmt.Printf("Worker %d shutting down\n", id)
return
default:
fmt.Printf("Worker %d working\n", id)
time.Sleep(500 * time.Millisecond)
}
}
}
func main() {
done := make(chan struct{})
numWorkers := 3
// 啟動(dòng)多個(gè)工作協(xié)程
for i := 1; i <= numWorkers; i++ {
go worker(i, done)
}
// 模擬一些工作
time.Sleep(2 * time.Second)
// 發(fā)送關(guān)閉信號(hào)
close(done)
// 等待一段時(shí)間以確保所有工作協(xié)程都已退出
time.Sleep(1 * time.Second)
}
在這個(gè)例子中,done 通道被用來通知所有工作協(xié)程停止工作。我們不需要通過通道傳遞任何實(shí)際的數(shù)據(jù),只需要一個(gè)信號(hào)即可。
.同步操作完成
package main
import (
"fmt"
"sync"
)
func task(id int, wg *sync.WaitGroup, done chan struct{}) {
defer wg.Done()
fmt.Printf("Task %d completed\n", id)
done <- struct{}{} // 發(fā)送一個(gè)空結(jié)構(gòu)體表示任務(wù)完成
}
func main() {
var wg sync.WaitGroup
done := make(chan struct{}, 3) // 緩沖區(qū)大小為任務(wù)數(shù)量
for i := 1; i <= 3; i++ {
wg.Add(1)
go task(i, &wg, done)
}
// 等待所有任務(wù)完成
go func() {
wg.Wait()
close(done)
}()
// 接收所有完成信號(hào)
for range done {
fmt.Println("Received completion signal")
}
fmt.Println("All tasks completed")
}
在這個(gè)例子中,每個(gè)任務(wù)完成后都會(huì)向 done 通道發(fā)送一個(gè)空結(jié)構(gòu)體,表示任務(wù)已完成。主協(xié)程通過讀取 done 通道中的信號(hào)來確認(rèn)所有任務(wù)是否已完成。
到此這篇關(guān)于go語(yǔ)言中空結(jié)構(gòu)體的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)go語(yǔ)言 空結(jié)構(gòu)體內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go代碼的組織和格式化規(guī)則實(shí)戰(zhàn)示例
這篇文章主要為大家介紹了Go代碼的組織和格式化示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
Go調(diào)度器學(xué)習(xí)之協(xié)作與搶占詳解
如果某個(gè)G執(zhí)行時(shí)間過長(zhǎng),其他的G如何才能被正常調(diào)度,這就引出了接下來的話題:協(xié)作與搶占。本文將通過一些示例為大家詳細(xì)講講調(diào)度器中協(xié)作與搶占的相關(guān)知識(shí),需要的可以參考一下2023-04-04
一文帶你了解Go語(yǔ)言中的I/O接口設(shè)計(jì)
I/O?操作在編程中扮演著至關(guān)重要的角色,它涉及程序與外部世界之間的數(shù)據(jù)交換,下面我們就來簡(jiǎn)單了解一下Go語(yǔ)言中的?I/O?接口設(shè)計(jì)吧2023-06-06

