zoukankan      html  css  js  c++  java
  • go channel pipeline 套路

    go channel pipeline 套路

    1. 起源

    一直想写关于pipeline的,但是深知自己在编程方面还是个菜,所以就直接引用the go programming language里面的例子了。照着写不容易出错。此书是永远的经典。

    2. pipeline1

    package main
    
    import "fmt"
    
    func main() {
    	naturals := make(chan int)
    	squares := make(chan int)
    
    	go func() {
    		for x := 0; ; x++ {
    			naturals <- x
    		}
    	}()
    
    	go func() {
    		for {
    			x := <-naturals
    			squares <- x * x
    		}
    	}()
    
    	for {
    		fmt.Println(<-squares)
    	}
    
    }
    

    所谓pipeline,中文就是流水线,函数通过chan传递变量,不需要传参数那种方式硬耦合了。
    这个例子中没有close,所以程序无限循环下去。
    当channel close的时候,再取就会失败,

    x,ok := <- naturals
    if !ok{
    	break
    }
    

    为此go语言简化了此类操作,设计了range的语法,很方便。

    3. pipeline2

    package main
    
    import "fmt"
    
    func main() {
    	naturals := make(chan int)
    	squares := make(chan int)
    
    	go func() {
    		for x := 0; x < 100; x++ {
    			naturals <- x
    		}
    		close(naturals)
    	}()
    
    	go func() {
    		for x := range naturals {
    			squares <- x * x
    		}
    		close(squares)
    	}()
    
    	for x := range squares {
    		fmt.Println(x)
    	}
    
    }
    

    close了以后,整个程序优雅结束。
    但是用匿名函数总不是长久之计,可以写成有名func。

    4. pipeline3

    package main
    
    import "fmt"
    
    func couter(out chan<- int) {
    	for x := 0; x < 100; x++ {
    		out <- x
    	}
    	close(out)
    }
    
    func squarer(out chan<- int, in <-chan int) {
    	for v := range in {
    		out <- v * v
    	}
    	close(out)
    
    }
    
    func printer(in <-chan int) {
    	for v := range in {
    		fmt.Println(v)
    	}
    }
    
    func main() {
    	natuals := make(chan int)
    	squares := make(chan int)
    	go couter(natuals)
    	go squarer(squares, natuals)
    	printer(squares)
    
    }
    
    

    go语言支持了定义unidirectional channel types(单向channel类型)

    1. chan <- int (send only)
    2. <- chan int (receive only)

    <- 在chan后面的是send only ,<- 在chan前面的的receive only。
    这种套路还是挺好用的,流水线了特别适合处理数据,比如说先获取,然后加工,最后再存到数据库中,如果传统那种做法是先获取数据,然后存到内存,之后处理数据,最后再存数据,时间上会比较长,也就是说前面的没做完后面的进行不了,空间上也很浪费,要把中间结果集存到内存中,数据量大的话内存还容易爆。

  • 相关阅读:
    ik_max_word ik_smart
    使用elasticsearch遇到的一些问题以及解决方法(不断更新)
    Install elasticsearch-head: – for Elasticsearch 5.x
    Spring实战5-基于Spring构建Web应用
    如何使用 Android Studio 的 git hub 功能
    windows中使用Git工具连接GitHub(配置篇)
    Git链接到自己的Github(2)进阶使用
    Git链接到自己的Github(1)简单的开始
    Android 自定义控件玩转字体变色 打造炫酷ViewPager指示器
    Android Studio 中快速提取方法
  • 原文地址:https://www.cnblogs.com/gqdw/p/13031693.html
Copyright © 2011-2022 走看看