基本語法和需要注意的點
- 語法定義
var channel chan [type]
- 使用
<-
傳遞資料 chan <- data
傳送資料到通道,向通道中寫資料data <- chan
獲取通道中的資料,從通道中讀取資料
- 使用
- 注意的點
- 它是用於
goroutine
之間進行傳遞訊息的 - 每個
channel
都有相關聯的資料型別,nil chan
不能使用 channel
是在goroutine
之間連結,資料接收和傳送必須處於不同的goroutine
中- 非緩衝通道傳送資料和讀取資料都是阻塞的,直到另一條
goroutine
執行讀取或寫完資料才會解除阻塞 channel
是同步的,就意味著同一時間,只能有一條goroutine
來操作- 不要忘記
close(channel)
關閉通道
- 它是用於
程式碼實現:
package main
import (
"fmt"
"strconv"
)
func main() {
// 建立通道
var channel chan int
fmt.Printf("%T,%v\n", channel, channel) // chan int,<nil>
channel = make(chan int)
fmt.Printf("%T,%v\n", channel, channel) // chan int,0xc00008c060
// 通道內寫入資料
go setData(channel)
// 讀取通道內的資料
for v := range channel {
fmt.Println("讀取的資料: ", v) // 讀取的資料:0,1,2,3,4
}
// 非緩衝通道
var ch1 chan int
ch1 = make(chan int)
go func() {
for i := 0; i < 5; i++ {
fmt.Println("子的 goroutine 中,i", i) // 子的 goroutine 中,i 0,1,2,3,4
}
// 迴圈結束後向通道中寫資料,表示結束了。
ch1 <- 1
fmt.Println("結束")
}()
data := <-ch1
fmt.Println("main data --> ", data)
/**
緩衝通道(固定大小)
接收:緩衝區資料空了會阻塞
寫入:緩衝區資料滿了會阻塞
*/
ch2 := make(chan int, 3)
fmt.Println(len(ch2), cap(ch2)) // 0 ,3
ch2 <- 1
ch2 <- 2
ch2 <- 3
fmt.Println(len(ch2), cap(ch2)) // 3,3
// 緩衝區滿了,如果需要繼續寫入資料,需要有其他的 goroutine 進行讀取(佇列的結構來讀取)
// ch2 <- 4
ch3 := make(chan string, 3)
fmt.Println(len(ch3), cap(ch3)) // 0 ,3
go setStringData(ch3, 3)
for {
v, ok := <-ch3
if !ok {
fmt.Println("讀取完畢", ok) // 讀取完畢 false
break
}
fmt.Println("讀取的資料是:", v) // 讀取的資料是: 0,1,2
}
/**
雙向通道
chan ch
chan <- data 寫入資料
data <- chan 讀取資料
*/
ch4 := make(chan string)
isDone := make(chan bool)
go SendString(ch4, isDone)
data1 := <-ch4 // 讀取
fmt.Println(data1) // golang
ch4 <- "learn golang" // 傳送
<-isDone // 判斷這個來看主程式結束
/**
單向通道:定向
chan <- Write 只支援寫
<- chan Read 只能讀
*/
singleChanWrite := make(chan<- int) // 只能寫,不能讀
singleChanRead := make(<-chan int) // 只能讀,不能寫
fmt.Println("main over")
}
func setData(ch chan int) {
for i := 0; i < 5; i++ {
ch <- i
}
close(ch) // 通知對方,通道關閉
}
func setStringData(ch chan string, number int) {
for i := 0; i < number; i++ {
ch <- strconv.Itoa(i)
}
close(ch) // 通知對方,通道關閉
}
func SendString(ch chan string, isDone chan bool) {
ch <- "golang" // 傳送
data2 := <-ch // 讀取資料
fmt.Println("main goroutine 傳來: ", data2) // main goroutine 傳來: learn golang
isDone <- true // 限制主程式過快的結束執行
}
*/
如想看學習記錄同步的練習程式碼移步 GitHub
本作品採用《CC 協議》,轉載必須註明作者和本文連結