只读只写channel
// 管道可以声明只读或者只写package mainimport "fmt"func main() {// 1、 默认情况下,管道是双向的,可读可写// var chan1 chan int// 2、只写var chan2 chan<- int = make(chan<- int, 3)chan2 <- 20fmt.Println("chan2 = ", chan2)// 3、只读var chan3 <-chan int// num1 := <-chan3// chan3 <- 3 // invalid operation: chan3 <- 3 (send to receive-only type <-chan int)fmt.Println("chan3 = ", chan3)}
select + channel
使用 select 解决 从 channel 中取数据的阻塞问题。
package mainimport ("fmt""strconv")func main() {// 创建带缓冲的管道var intChan chan int = make(chan int, 5)for i := 0; i < 5; i++ {intChan <- i}// 创建带缓冲的管道var strChan chan string = make(chan string, 10)for i := 0; i < 10; i++ {strChan <- "hello" + strconv.Itoa(i)}// 传统方法遍历管道,如果不关闭会阻塞而导致 deadlock// 不确定什么时候关闭管道,可以使用 select 语法解决for {select {case v := <-intChan:fmt.Printf("从 intChan 中取到数据%d \n", v)case v := <-strChan:fmt.Printf("从 strChan 中取到数据%v \n", v)default:fmt.Println("都取不到,不玩了")return}}/*从 strChan 中取到数据hello0从 strChan 中取到数据hello1从 intChan 中取到数据0从 strChan 中取到数据hello2从 intChan 中取到数据1从 strChan 中取到数据hello3从 intChan 中取到数据2从 strChan 中取到数据hello4从 strChan 中取到数据hello5从 intChan 中取到数据3从 strChan 中取到数据hello6从 intChan 中取到数据4从 strChan 中取到数据hello7从 strChan 中取到数据hello8从 strChan 中取到数据hello9都取不到,不玩了*/}
goroutine + recover(错误捕获)
goroutine 中使用 recover ,解决协程中出现 panic 导致程序崩溃问题
// recoverpackage mainimport ("fmt""sync")var wg sync.WaitGroupfunc sayHello() {defer wg.Done()for i := 0; i < 10; i++ {fmt.Println("hello")}}func test() {// defer + recover 捕获处理异常defer func() {wg.Done()if err := recover(); err != nil {// 有异常fmt.Println("test() err = ", err)// test() err = assignment to entry in nil map}}()var testmap map[int]string// var testmap = make(map[int]string)testmap[0] = "北京" // 没有分配空间 (make) error}func main() {fmt.Println("程序开始了")wg.Add(2)// recovergo sayHello()go test()wg.Wait()fmt.Println("程序结束了")}
