通道(channels) 是連接多個協程的管道,可以從一個協程將值發送到通道,然後在另一個協程中接收,由關鍵字chan
定義
使用 make(chan val-type)
創建一個新的通道。 通道類型就是需要傳遞值的類型
發送:channel <- info
發送 一個新的值到通道中
接收:<-channel
通道的兩種類型:無緩衝(默認)、有緩衝
例子1 :無緩衝通道,併發接收
package main
import (
"fmt"
)
func main() {
message := make(chan string) //無緩衝通道
go func() {
message <- "ping" //channel <- 語法 發送 一個新的值到通道中
message <- "hhh"
}()
msg := <-message // <-channel 語法從通道中 接收 一個值
fmt.Println(msg)
msg2 := <-message
fmt.Println(msg2)
}
結果
例子2:有緩衝通道,無需設置併發
package main
import "fmt"
func main() {
messages := make(chan string, 2) //由於此通道是有緩衝的, 因此我們可以將這些值發送到通道中,而無需併發的接收。
messages <- "buffered"
messages <- "channel"
fmt.Println(<-messages)
fmt.Println(<-messages)
}
例子3:常見報錯, fatal error: all goroutines are asleep - deadlock!
package main
import "fmt"
func main() {
messages := make(chan string) //這次不設置緩衝
messages <- "buffered"
fmt.Println(<-messages)
}
會報錯: fatal error: all goroutines are asleep - deadlock!
make(chan string),開闢的通道是一種無緩衝通道,所以當對這個緩衝通道寫的時候,會一直阻塞等到某個協程對這個緩衝通道讀,所以執行到messages <- "buffered"
時,會產生阻塞,由於沒有設置並行接收器,所以會一直等待