注: 本笔记是自己的学习笔记,都是自己的理解,而不是教学文章,要学习请自行阅读 图书 --- Go程序设计语言
goroutine 很好理解了,就是并发的执行体。 多协成的执行一段代码。
而通道是一个 go 发送到另一个go的通信机制。 每一个通道也都有类型,叫通道的元素类型。 一个有int类型的元素写为
chan int
创建通道用make
ch := make(chan int)
通道分发送和接收,通道和值分别在<-的左右两边
ch <- x // 发送语句
ch是通道, x是值。
通道 ch 发送x值
x = <-ch //
<-ch // 接收语句
注意 通道ch 在左边就是发送语句,在右边就是接收语句。
当通道接收值时, 就是 <-ch 的时候, 其接收的结果是非必须值
x = <-ch // x是接收结果
<-ch // 通道接收值, 丢弃结果
close(ch) // 关闭通道
用完记得关闭
make可以接收第二个参数, 表示通道容量, 为0或不传值时,是无缓冲通道
ch = make(chan int) // 无缓冲通道
ch = make(chan int, 0) // 无缓冲通道
ch = make(chan int, 3) // 容量为3的缓冲通道
无缓冲通道,我的理解,简单说,A端发送,B端接收。
1,A发送了,没有接收,A会阻塞,就是卡住了。
2,B接收了,没有收到消息, B也会卡住,等待传值。
这里理解的不对。准确的说是从一个没有值的通道获取,会卡住。
但从一个已关闭的通道获取值,有值则获取,没值会活取类型空值。
3, A发送了,B接收了。 然后A,B,都继续干自己的活。
通道并不是A脚本和B脚本通信, 他们通常在同一段代码中, 只不过go 后面的函数, 是多协成,会同时执行, 通道是他们之间通信。
通道好多时候更像一个数组。
管道: 一个输出是另一个的输入。
package main
import (
"fmt"
_"log"
)
func main() {
naturals := make(chan int)
squares := make(chan int)
go func() {
// 这里没有条件 会无限循环下去
// 这段代码能把你电脑跑死,所以我添加了x的条件
for x := 0; x < 3; x++ {
naturals <- x
}
}()
// 这小括号是匿名函数输入参数值
// 必须写上 不然报错
go func() {
for {
x := <-naturals
squares <- x * x
}
}()
for {
fmt.Printf("<-squares = ")
fmt.Println(<-squares)
}
}
在得到0,1,4后报错了。
可以把通道看出数组,用for range, 用完记得关闭
package main
import (
"fmt"
_ "log"
)
func main() {
naturals := make(chan int)
squares := make(chan int)
go func() {
// 这里没有条件 会无限循环下去
// 这段代码能把你电脑跑死,所以我添加了x的条件
for x := 0; x < 3; x++ {
naturals <- x
}
close(naturals)
}()
// 这小括号是匿名函数输入参数值
// 必须写上 不然报错
go func() {
for x := range naturals{
squares <- x * x
}
close(squares)
}()
for x := range squares{
fmt.Println(x)
}
}
网友评论