go语言的channel使用注意事项

package main

import (
        "fmt"
        "time"
)


//fixme channel注意事项

func main() {
        //todo 1. chan 可以声明为只读或者只写 默认是读写都可用
        //只写
        //var writeChan chan<- int = make(chan int, 3)
        //writeChan <- 3
        //<- intChan //编译不通过 intChan (receive from send-only type
        
        //只读
        //var readChan <-chan int = make(chan int, 3)
        //readChan <- 3 //运行时报错 intChan2 <- 3 (send to receive-only type

        //todo 2. 使用chan完成后记得注意关闭,不关闭阻塞会导致deadlock 如果太麻烦可以使用select

        //intChan := make(chan int, 6)
        //
        //for i := 0; i < 6; i++ {
        //      intChan <- i
        //}
        //
        //stringChan := make(chan string, 6)
        //for i := 0; i < 6; i++ {
        //      stringChan <- "data:" + fmt.Sprintf("%d", i)
        //}
        //
        //for {
        //      select {
        //      case val := <-intChan:
        //              fmt.Println(val)
        //      case val := <-stringChan:
        //              fmt.Println(val)
        //      default:
        //              //fmt.Println("做其他事")
        //              return
        //      }
        //
        //}


        //todo 3. 使用recover, 解决协程中出现panic,导致程序崩溃
        go test()
        go test2()
        time.Sleep(time.Second)
        fmt.Println("ok")


        //todo 4. 如果chan容量满了还在增加元素,或者chan没有元素还在获取元素,或者没关闭chan就遍历元素都是会报deadlock的.
}

func test()  {
        defer func() {
                //捕获panic
                if err := recover(); err != nil {
                        fmt.Println("test() 发生错误:", err)
                }
        }()

        var dataMap map[int]string
        dataMap[0] = "go"
}

func test2()  {
        for i := 0; i < 10; i++ {
                time.Sleep(time.Second)
                fmt.Println(i + 10)
        }
}