golang的struct{}類型channel

golang的struct{}類型channel

struct{}是個什么鬼

之前看代碼的時候發(fā)現(xiàn)有如下定義的channel,就覺得很詫異

var ch chan struct{}

這其中,struct{}是個什么鬼。

實(shí)際上struct{}就是一種普通數(shù)據(jù)類型,只是沒有具體的值而已。

常用用法

通常struct{}類型channel的用法是使用同步,一般不需要往channel里面寫數(shù)據(jù),只有讀等待,而讀等待會在channel被關(guān)閉的時候返回。

package main

import (
    "time"
    "log"
)

var ch chan struct{} = make(chan struct{})

func foo() {
    
    log.Println("foo() 111");
    time.Sleep(5 * time.Second)
    log.Println("foo() 222");
    close(ch)
    log.Println("foo() 333");
}

func main() {
    
    log.Println("main() 111");
    go foo()
    log.Println("main() 222");
    <-ch
    log.Println("main() 333");
}

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

2018/04/12 06:46:33 main() 111
2018/04/12 06:46:33 main() 222
2018/04/12 06:46:33 foo() 111
2018/04/12 06:46:38 foo() 222
2018/04/12 06:46:38 foo() 333
2018/04/12 06:46:38 main() 333

在main函數(shù)里面ch讀操作一直等待foo調(diào)用close(ch)才返回。

注意啊,channel對象一定要make出來才能使用。

往chann struct{}寫入數(shù)據(jù)

另一個問題,我們能不能往struct{}類型的channel里面寫數(shù)據(jù)呢,答案當(dāng)然也是可以的。

package main

import (
    "time"
    "log"
)

var ch chan struct{} = make(chan struct{})

func foo() {
    ch <- struct{}{}
    log.Println("foo() 111");
    time.Sleep(5 * time.Second)
    log.Println("foo() 222");
    close(ch)
    log.Println("foo() 333");
}

func main() {
    
    log.Println("main() 111");
    go foo()
    log.Println("main() 222");
    <-ch
    log.Println("main() 333");
}

在foo()入口處給ch賦了一個值
注意寫法是"struct{}{}",第一個"{}"對表示類型,第二個"{}"對表示一個類型對象實(shí)例。

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

2018/04/12 06:50:16 main() 111
2018/04/12 06:50:16 main() 222
2018/04/12 06:50:16 foo() 111
2018/04/12 06:50:16 main() 333

由于在foo()啟動的時候往ch里面寫入了一個對象,所以在main()函數(shù)里面不需要等待close(ch)就能拿到一個值,因此main()函數(shù)可以馬上退出,不需要等到foo()的Sleep()完成。

帶緩沖的chan struct{}數(shù)據(jù)讀寫

另外也可以定義帶緩沖的channel

package main

import (
    "time"
    "log"
)

var ch chan struct{} = make(chan struct{}, 2)

func foo() {
    ch <- struct{}{}
    log.Println("foo() 000");
    ch <- struct{}{}
    log.Println("foo() 111");
    time.Sleep(5 * time.Second)
    log.Println("foo() 222");
    close(ch)
    log.Println("foo() 333");
}

func main() {
    var b struct{}
 
    log.Println("main() 111");
    go foo()
    log.Println("main() 222");
    a := <-ch
    log.Println("main() 333", a);
    b  = <-ch
    log.Println("main() 444", b);
    c := <-ch
    log.Println("main() 555", c);
}

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

2018/04/12 06:58:06 main() 111
2018/04/12 06:58:06 main() 222
2018/04/12 06:58:06 foo() 000
2018/04/12 06:58:06 foo() 111
2018/04/12 06:58:06 main() 333 {}
2018/04/12 06:58:06 main() 444 {}
2018/04/12 06:58:11 foo() 222
2018/04/12 06:58:11 foo() 333
2018/04/12 06:58:11 main() 555 {}

帶兩個緩沖大小的channel;
另外我們可以看到,其實(shí)也可以從channel里面讀出數(shù)據(jù)來,但是這種數(shù)據(jù)顯然沒有實(shí)際意義。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,534評論 19 139
  • 選擇題 [primary] 下面屬于關(guān)鍵字的是() A. func B. def C. struct D. cla...
    盤木閱讀 1,873評論 0 29
  • channel[通道]是golang的一種重要特性,正是因?yàn)閏hannel的存在才使得golang不同于其它語言。...
    碼洞閱讀 22,663評論 1 53
  • 今年的第三個大滿貫賽事,美網(wǎng)即將開戰(zhàn),希望、期待、懸念、猜測一股腦般地裝滿了網(wǎng)球愛好者的頭腦,最渴望、最期待的莫過...
    ZHANGAQ閱讀 320評論 0 0
  • 聽過無數(shù)遍一個問題,這個問題應(yīng)該是所有處在迷茫期的有志青年都在思考的問題:是留在北上廣還是回家? 是啊,好難的問題...
    黃小蟻閱讀 332評論 1 0

友情鏈接更多精彩內(nèi)容