Go管道注意细节
Posted yzg-14
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go管道注意细节相关的知识,希望对你有一定的参考价值。
package main import ( "fmt" ) func main() { //管道可以声明为只读或者只写 //1. 在默认情况下下,管道是双向 //var chan1 chan int //可读可写 //2 声明为只写 var chan2 chan<- int chan2 = make(chan int, 3) chan2<- 20 //num := <-chan2 //error fmt.Println("chan2=", chan2) //chan2= 0xc000094000 //3. 声明为只读 var chan3 <-chan int fmt.Println("chan3", chan3) //chan3 <nil> num2 := <-chan3 //报错 //用在方法参数的类型中 //chan3<- 30 //err fmt.Println("num2", num2) }
package main import ( "fmt" _ "time" ) func main() { //使用select可以解决从管道取数据的阻塞问题 //1.定义一个管道 10个数据int intChan := make(chan int, 10) for i := 0; i < 10; i++ { intChan <- i } fmt.Printf("%v ", intChan) //0xc00007a000 //2.定义一个管道 5个数据string stringChan := make(chan string, 5) for i := 0; i < 5; i++ { stringChan <- "hello" + fmt.Sprintf("%d", i) } fmt.Printf("%v ", stringChan) //传统的方法在遍历管道时,如果不关闭会阻塞而导致 deadlock //for { // v := <-intChan // fmt.Printf("从intChan读取的数据%d ", v) //} //问题,在实际开发中,可能我们不好确定什么关闭该管道. //可以使用select 方式可以解决 //label: for { select { //注意: 这里,如果intChan一直没有关闭,不会一直阻塞而deadlock,会自动到下一个case匹配 case v := <-intChan: fmt.Printf("从intChan读取的数据%d ", v) //time.Sleep(time.Second) case v := <-stringChan: fmt.Printf("从stringChan读取的数据%s ", v) //time.Sleep(time.Second) default: //都取不到 fmt.Printf("都取不到了,不玩了, 程序员可以加入逻辑 ") //time.Sleep(time.Second) return //break //只能跳到select //break label //跳到第一个lable标签那去 } } } //=========顺序无法控制============= //0xc000092000 //0xc000098000 //从intChan读取的数据0 //从intChan读取的数据1 //从intChan读取的数据2 //从intChan读取的数据3 //从stringChan读取的数据hello0 //从stringChan读取的数据hello1 //从intChan读取的数据4 //从stringChan读取的数据hello2 //从stringChan读取的数据hello3 //从intChan读取的数据5 //从stringChan读取的数据hello4 //从intChan读取的数据6 //从intChan读取的数据7 //从intChan读取的数据8 //从intChan读取的数据9 //都取不到了,不玩了, 程序员可以加入逻辑
package main import ( "fmt" _ "time" ) //函数 func sayHello() { for i := 0; i < 10; i++ { //time.Sleep(time.Second) fmt.Println("hello,world") } } //函数 func test() { //这里我们可以使用defer + recover defer func() { //捕获test这个函数(多协程时,这个协程)抛出的panic if err := recover(); err != nil { fmt.Println("test() 发生错误", err) } }() //定义了一个map var myMap map[int]string myMap[0] = "golang" // 这里会报错 } func main() { go sayHello() go test() for i := 0; i < 10; i++ { fmt.Println("main() ok=", i) //time.Sleep(time.Second) } }
以上是关于Go管道注意细节的主要内容,如果未能解决你的问题,请参考以下文章