golang的struct{}類型channel


golang的struct{}類型channel

struct{}是結構體類型的代表;

struct{}{}是結構體的值,並且值為空的代表

之前看代碼的時候發現有如下定義的channel,就覺得很詫異

var ch chan struct{} 

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

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

常用用法

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

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"); } 

運行結果為

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函數里面ch讀操作一直等待foo調用close(ch)才返回。

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

往chann struct{}寫入數據

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

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{}{}",第一個"{}"對表示類型,第二個"{}"對表示一個類型對象實例。

運行結果:

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()函數里面不需要等待close(ch)就能拿到一個值,因此main()函數可以馬上退出,不需要等到foo()的Sleep()完成。

帶緩沖的chan struct{}數據讀寫

另外也可以定義帶緩沖的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); } 

運行結果為

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;
另外我們可以看到,其實也可以從channel里面讀出數據來,但是這種數據顯然沒有實際意義。



作者:CodingCode
鏈接:https://www.jianshu.com/p/7f45d7989f3a
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM