扫码订阅《 Go语言基础进阶》或入驻星球,即可阅读文章!

GOLANG ROADMAP

阅读模式

  • 沉浸
  • 自动
  • 日常
首页
Go友会
  • 城市
  • 校园
Go学院
  • Go小课
  • Go小考
  • Go实战
  • 精品课
Go求职
  • 求职辅导🔥
  • Offer收割社群
  • 企业题库
  • 面试宝典
Go宝典
  • 在线宝典
  • B站精选
  • 推荐图书
  • 每日博文
Go仓库
实验区
  • Go周边
  • Go下载
  • Go月刊
消息
更多
  • 用户中心

    • 我的信息
    • 推广返利
  • 玩转星球

    • 星球介绍
    • 角色体系
    • 星主权益
  • 支持与服务

    • 联系星主
    • 成长记录
    • 常见问题
    • 吐槽专区
  • 合作交流

    • 渠道合作
    • 课程入驻
    • 友情链接
author-avatar

GOLANG ROADMAP


首页
Go友会
  • 城市
  • 校园
Go学院
  • Go小课
  • Go小考
  • Go实战
  • 精品课
Go求职
  • 求职辅导🔥
  • Offer收割社群
  • 企业题库
  • 面试宝典
Go宝典
  • 在线宝典
  • B站精选
  • 推荐图书
  • 每日博文
Go仓库
实验区
  • Go周边
  • Go下载
  • Go月刊
消息
更多
  • 用户中心

    • 我的信息
    • 推广返利
  • 玩转星球

    • 星球介绍
    • 角色体系
    • 星主权益
  • 支持与服务

    • 联系星主
    • 成长记录
    • 常见问题
    • 吐槽专区
  • 合作交流

    • 渠道合作
    • 课程入驻
    • 友情链接
  • 课程介绍

    • 《Go语言基础进阶》
  • 包管理

  • IO操作

  • 并发Goroutine&Channel

    • 第1节:并发编程介绍
    • 第2节:并发性Concurrency
    • 第3节:Go语言的协程——Goroutine
    • 第4节:Go语言的并发模型
    • 第5节:runtime包
    • 第6节:临界资源安全问题
    • 第7节:sync包——WaitGroup
    • 第8节:sync包——互斥锁
    • 第9节:sync包——读写锁
    • 第10节:channel通道
    • 第11节:关闭通道和通道上范围循环
    • 第12节:缓冲通道
    • 第13节:定向通道
    • 第14节:time包中的通道相关函数
    • 第15节:select语句
    • 第16节:Go语言的CSP模型
  • 反射机制

扫码订阅《 Go语言基础进阶》或入驻星球,即可阅读文章!

第13节:定向通道


GOLANG ROADMAP

# 一、双向通道

通道,channel,是用于实现goroutine之间的通信的。一个goroutine可以向通道中发送数据,另一条goroutine可以从该通道中获取数据。截止到现在我们所学习的通道,都是既可以发送数据,也可以读取数据,我们又把这种通道叫做双向通道。

data := <- a // read from channel a  
a <- data // write to channel a
1
2

# 二、单向通道

单向通道,也就是定向通道。

之前我们学习的通道都是双向通道,我们可以通过这些通道接收或者发送数据。我们也可以创建单向通道,这些通道只能发送或者接收数据。

双向通道,实例代码:

package main

import "fmt"

func main()  {
    /*
    双向:
        chan T -->
            chan <- data,写出数据,写
            data <- chan,获取数据,读
    单向:定向
        chan <- T,
            只支持写,
        <- chan T,
            只读
     */
    ch1 := make(chan string) // 双向,可读,可写
    done := make(chan bool)
    go sendData(ch1, done)
    data :=<- ch1 //阻塞
    fmt.Println("子goroutine传来:", data)
    ch1 <- "我是main。。" // 阻塞

    <-done
    fmt.Println("main...over....")
}
//子goroutine-->写数据到ch1通道中
//main goroutine-->从ch1通道中取
func sendData(ch1 chan string, done chan bool)  {
    ch1 <- "我是小明"// 阻塞
    data := <-ch1 // 阻塞
    fmt.Println("main goroutine传来:",data)

    done <- true
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

运行结果:

创建仅能发送数据的通道,示例代码:

示例代码:

package main

import "fmt"

func main()  {
    /*
        单向:定向
        chan <- T,
            只支持写,
        <- chan T,
            只读

        用于参数传递:
     */
    ch1 := make(chan int)//双向,读,写
    //ch2 := make(chan <- int) // 单向,只写,不能读
    //ch3 := make(<- chan int) //单向,只读,不能写
    //ch1 <- 100
    //data :=<-ch1
    //ch2 <- 1000
    //data := <- ch2
    //fmt.Println(data)
    //  <-ch2 //invalid operation: <-ch2 (receive from send-only type chan<- int)
    //ch3 <- 100
    //  <-ch3
    //  ch3 <- 100 //invalid operation: ch3 <- 100 (send to receive-only type <-chan int)

    //go fun1(ch2)
    go fun1(ch1)
    data:= <- ch1
    fmt.Println("fun1中写出的数据是:",data)

    //fun2(ch3)
    go fun2(ch1)
    ch1 <- 200
    fmt.Println("main。。over。。")
}
//该函数接收,只写的通道
func fun1(ch chan <- int){
    // 函数内部,对于ch只能写数据,不能读数据
    ch <- 100
    fmt.Println("fun1函数结束。。")
}

func fun2(ch <-chan int){
    //函数内部,对于ch只能读数据,不能写数据
    data := <- ch
    fmt.Println("fun2函数,从ch中读取的数据是:",data)
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

运行结果:

  • 一、双向通道
  • 二、单向通道