### chanel類型
用于多個協程之間的通信,channel是一種特殊類型,和map類似
> **var 通道變量 chan 通道類型**
>
定義channel時,也需要定義發送到channel的值的類型,可以使用make()函數創建
> **make(chan Type) ,等價于 make(chan Type, 0)**
> **make(chan Type, capacity)**
> Type,類型
>
當capacity (容量) 為0時,channel是無緩沖堵塞讀寫的,當capacity大于0時,channel是有緩沖,非堵塞的,直到寫滿capacity個元素才堵塞寫入。
channel 通過 "<-" 來接收和發送數據
默認channel收發數據都是堵塞的
```
channel <- value //發送value到channel
<- channel //接收并將其丟棄
x := <- channel //從channel中接收數據,賦值給x
x, ok = <- channel //從channel中接收數據賦值給x,檢查通道是否關閉將此狀態賦值給ok
```
```
package main
import (
"fmt"
"time"
)
func main() {
// 創建通道
ch := make(chan string)
go func() {
// 打印通道接收的 值
fmt.Println(<-ch)
}()
// 發送 hello 到到通道 ch
ch <- "hello"
time.Sleep(time.Second)
}
結果:
hello
```
### 緩沖機制
無緩沖通道,是指接收前沒有能力保存任何值的通道
> **make(chan Type),等價于 make(chan Type, 0)**
>
無緩沖通道ch,只有當接收者接收到數據,發送者才能繼續發送
```
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int, 0)
go func() {
for i := 0; i < 3; i++ {
fmt.Printf("長度len() = %v, 容量cap(ch)=%v\n", len(ch), cap(ch))
// 把 i 發送給通道 ch
ch <- i
}
}()
for i := 0; i < 3; i++ {
time.Sleep(time.Second)
// 打印接收的通道 ch
fmt.Println(<-ch)
}
}
結果:
長度len() = 0, 容量cap(ch)=0
0
長度len() = 0, 容量cap(ch)=0
1
長度len() = 0, 容量cap(ch)=0
2
```
有緩存通道,是指被接收前能儲存一個或者多個值的通道
>**make(chan Type, capatity)**
```
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int, 3)
go func() {
for i := 0; i < 3; i++ {
fmt.Printf("長度len() = %v, 容量cap(ch)=%v\n", len(ch), cap(ch))
// 把 i 發送給通道 ch
ch <- i
}
}()
for i := 0; i < 3; i++ {
time.Sleep(time.Second)
// 打印接收的通道 ch
fmt.Println(<-ch)
}
}
結果:
長度len() = 0, 容量cap(ch)=3
長度len() = 1, 容量cap(ch)=3
長度len() = 2, 容量cap(ch)=3
0
1
2
```
### close 和range
close和range 讓通道停止不必要的等待
.
**close**
channel不像文件可以經常關閉,只有當你沒有需要發送的數據時,或者想結束range循環之類的,才會關閉
關閉后無法再錯向channel發送數據,但是可以從channel接收
對于nil channel(空通道)無論接收還是發送都會堵塞
```
package main
import "fmt"
func main() {
// 創建一個通道
ch := make(chan int, 3)
go func() {
for i := 0; i < 3; i++ {
fmt.Printf("長度len() = %v, 容量cap(ch)=%v\n", len(ch), cap(ch))
// 發送i給通道
ch <- i
}
// 關閉通道
close(ch)
}()
for i := 0; i < 3; i++ {
// 如果通道里面有值 ok 就等于 true 沒有了就是false 執行else
if val, ok := <-ch; ok == true {
fmt.Println(val)
} else {
return
}
}
}
結果:
長度len() = 0, 容量cap(ch)=3
長度len() = 0, 容量cap(ch)=3
長度len() = 1, 容量cap(ch)=3
0
1
2
```
.
**range遍歷通道**
```
for data:= range ch{
}
```
```
package main
import "fmt"
func main() {
// 創建一個通道
ch := make(chan int, 3)
go func() {
for i := 0; i < 3; i++ {
fmt.Printf("長度len() = %v, 容量cap(ch)=%v\n", len(ch), cap(ch))
// 發送i給通道
ch <- i
}
// 關閉通道
close(ch)
}()
// 遍歷通道
for data := range ch {
fmt.Println(data)
}
}
結果:
長度len() = 0, 容量cap(ch)=3
長度len() = 0, 容量cap(ch)=3
長度len() = 1, 容量cap(ch)=3
0
1
2
```
- 安裝開發環境
- 安裝開發環境
- 安裝詳細教程
- 引入包
- Go語言基礎
- 基本變量與數據類型
- 變量
- 數據類型
- 指針
- 字符串
- 代碼總結
- 常量與運算符
- 常量
- 運算符
- 流程控制
- if判斷
- for循環
- switch分支
- goto跳轉
- 斐波那契數列
- Go語言內置容器
- 數組
- 切片
- 映射
- 函數
- 函數(上)
- 函數(中)
- 函數(下)
- 小節
- 包管理
- 結構體
- 結構體(上)
- 結構體(中)
- 結構體(下)
- 小節
- 錯誤處理
- 錯誤處理
- 宕機
- 錯誤應用
- 小節
- 文件操作
- 獲取目錄
- 創建和刪除目錄
- 文件基本操作(上)
- 文件基本操作(中)
- 文件基本操作(下)
- 處理JSON文件
- 接口與類型
- 接口的創建與實現
- 接口賦值
- 接口嵌入
- 空接口
- 類型斷言(1)
- 類型斷言(2)
- 小節
- 并發與通道
- goroutine協程
- runtime包
- 通道channel
- 單向通道channel
- select
- 線程同步
- 多線程的深入學習
- http編程
- http簡介
- Client和Request
- get請求
- post請求
- 模塊函數方法
- 模塊
- fmt庫,模塊
- 項目練習
- 爬蟲:高三網
- 爬蟲:快代理
- 爬蟲:快代理2
- 多線程:通道思路
- 多線程爬蟲:快代理