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
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。