Go元素的关键字所在--chan通道

广告:宝塔服务器面板,一键全能部署及管理,送你10850元礼包,点我领取~~~

Go元素的关键字所在--chan通道

HTML validate是指HTML验证。它是通过与标准HTML规则进行比较的方式,分析HTML文档、标记出错误和非标准代码的处理过程。Web页面使用HTML进行渲染,而HTML本身采用了HTML规范作为其规则和标准。通过验证HTML代码穿越多重浏览器标准!

chan

chan又称之为通道,形式类似于管道,内容从一头被送进去,从另一头被读取出来。下边来介绍定义通道的方法:

var 变量名 chan dataType
登录后复制

定义通道时,需要指定数据类型,就是只允许这个指定数据类型的变量通过这个通道。

初始化通道

golang中在初始化通道类型变量时,可以将通道分为两种情况,一种是带缓冲的通道,另一种是不带缓冲的通道。 下边来介绍下两种情况的初始化方法:

// 初始化不带缓冲的通道,通道中数据类型是intvar ch1 = make(chan int)// 初始化带10个缓冲的通道,通道中数据类型是stringvar ch2 = make(chan string,10)
登录后复制

还有一种写法是,定义并初始化通道,

// 定义通道,并给通道初始化8个缓冲ch3 := make(chan int ,8)// 定义通道,并初始化为不带缓冲通道ch4 := make(chan string)
登录后复制

通道赋值

对通道的读取和写入都可能进入阻塞状态。

不带缓冲的通道,在写入时,就会发生阻塞,直到通道中信息被读取后,才会结束阻塞。

带缓冲的通道,每次向通道中写入一次信息,通道长度就会加1,每成功从通道读取一次信息,通道长度减1。如果通道长度等于通道缓冲长度时,向通道继续写入信息会使程序阻塞;如果通道长度小于通道缓冲长度,则向通道中写入信息不会造成阻塞。假如通道长度是5,那么在通道没有被读取的情况下,向通道中第6次写入信息时才会导致程序阻塞。

通道写入的语法格式是:

var ch = make(chan string,10)// 将字符串”hello"写入到通道中,通道长度加1ch <- "hello"
登录后复制

读取通道

通道为空 1. 通道没有关闭,程序会进入阻塞状态,等到通道有信息写入 2. 通道已经关闭,不会阻塞,返回通道中数据类型初始值(脏数据),如通道是chan int时,返回值是0,通道是chan string时,返回值是空。 通道不为空 1. 通道没有关闭,从通道中读取一次信息,读取完成后,往下执行 2. 通道已被关闭,从通道中读取一次信信,读取完成后,往下执行

读取通道操作:

val,ok := <-ch
登录后复制

使用断言读取通道中的值,检查通道是否还有内容,以及判断通道是否已经关闭,当通道中没有信息,且通道已经关闭时,ok值为false,当通道没有关闭,但是通道中没有信息,程序将会阻塞,如果通道中有内容,则ok值是true。

另一种不使用断言的方式读取通道

val := <-ch
登录后复制

写入与读取通道

读取不带缓冲的通道示例方法:

package mainimport (    "fmt")func main() {    // 定义一个不带缓冲的通道,通道中数据类型是int    var c = make(chan int)    // 开启一个携程,读取通道中的内容    go func() {        fmt.Println("写入信息是:", <-c)    }()    // 向通道中写入数据    c <- 1}
登录后复制

输出结果:

写入信息是: 1
登录后复制

当对带缓冲的通道进行读写时,只要通道中数据长度不大于缓冲长度,就不会出现阻塞,但是读取带缓冲的通道,通道中没有内容时,程序依然会进入阻塞状态。所以,带缓冲的通道,只对写入产生影响。下边来一个示例:

package mainimport (    "fmt")func main() {    var c = make(chan int, 3)    c <- 1    c <- 2    c <- 3    //c <- 4    fmt.Println("end")}
登录后复制

输出信息是:

end
登录后复制

当向带3个缓冲的通道中写入内容时,由于只写入了3次,通道的长度刚好等于缓冲的长度,程序没有阻塞,当将 c <- 4 前边的注释去掉后,由于没有程序去读取这个通道,主程序进入死锁状态而导致异常。

协程通信

通道类型变量的实质上是一个地址,如下边示例代码:

// 初始化不带缓冲的通道,通道中数据类型是intvar ch1 = make(chan int)// 初始化带10个缓冲的通道,通道中数据类型是stringvar ch2 = make(chan string,10)0
登录后复制

输出结果:

// 初始化不带缓冲的通道,通道中数据类型是intvar ch1 = make(chan int)// 初始化带10个缓冲的通道,通道中数据类型是stringvar ch2 = make(chan string,10)1
登录后复制

所以,当通道类型变量当做参数传入函数后,在函数中可以直接对通道中的值进行修改。虽然chan类型变量是一个地址,但是golang不允许使用取值操作符( * )来操作chan类型变量。但是如果你先对chan类型变量使用取地址操作符(&),然后再使用取值操作符(*),这种操作方法还是可以正常运行的,但是这意义不大,除非你的目的是在函数调用中,重新定义一个chan类型变量替换原来的变量。

chan的这些特性,可以很好的实现协程之间的同步功能。不带缓冲的通道,是一种零容忍的等待,可以实现强制同步;带缓冲的通道,是有一定量容忍度的等待,可以实现允许有一定时间差的同步。

简单的协程间通信例子:

// 初始化不带缓冲的通道,通道中数据类型是intvar ch1 = make(chan int)// 初始化带10个缓冲的通道,通道中数据类型是stringvar ch2 = make(chan string,10)2
登录后复制

输出信息是:

// 初始化不带缓冲的通道,通道中数据类型是intvar ch1 = make(chan int)// 初始化带10个缓冲的通道,通道中数据类型是stringvar ch2 = make(chan string,10)3
登录后复制

相关推荐:

HTML validate HTML验证_HTML/Xhtml_网页制作

HTML技巧汇编_CSS/HTML

以上就是Go元素的关键字所在--chan通道的详细内容,更多请关注9543建站博客其它相关文章!

9543建站博客
一个专注于网站开发、微信开发的技术类纯净博客。
作者头像
admin创始人

肥猫,知名SEO博客站长,14年SEO经验。

上一篇:详解HTML5新增的多媒体标签
下一篇:浅析Node的events模块

发表评论

关闭广告
关闭广告