Func pipe in go Language

huangapple go评论70阅读模式
英文:

Func pipe in go Language

问题

在Go语言中,可以创建函数管道,其中一个函数的输出直接传递给另一个函数的输入。

以下是使用通道(channels)的代码示例:

type TestObj struct {
    // 定义TestObj的结构
}

func processA(input <-chan TestObj, output chan<- TestObj) {
    // 处理input,并将结果发送到output通道
    test := <-input
    // do something
    output <- test
}

func processB(input <-chan TestObj, output chan<- TestObj) {
    // 处理input,并将结果发送到output通道
    test := <-input
    // do something
    output <- test
}

func processC(input <-chan TestObj, output chan<- TestObj) {
    // 处理input,并将结果发送到output通道
    test := <-input
    // do something
    output <- test
}

func main() {
    obj := TestObj{}
    input := make(chan TestObj)
    output := make(chan TestObj)

    go processA(input, output)
    go processB(output, input)
    go processC(input, output)

    input <- obj

    result := <-output
    // 处理最终的结果
}

在这个示例中,我们使用了通道来实现函数之间的数据传递。每个函数都从输入通道(input)接收数据,并将处理后的结果发送到输出通道(output)。通过将输出通道与输入通道连接起来,我们可以实现函数之间的连续处理。

英文:

is it possible to create function pipelines in go language, where output of one function is directly conventionality into input of another function.

Please discuss it in the comments if it's not clear and you need more info.

Other functional languages provide some constructs, for instance it's then in javascript with promises, in java they use andThen with lambdas, and with c# it's FunctionExtensions. Shell programs like unix also provides buitin method called pipes |

func processA(test TestObj) {
	// do something
	return test
}

func process B(test TestObj) {
	//do something
	return test
}

func processC(test TestObj) {
	//do something
	return test
}

so can we do something similar like

var obj = TestObj{}

processA(obj)
   .then(processB)
    .then(processC)

jim, the second example uses the channels? can you please provide a code example using my code.

答案1

得分: 2

我也一直在寻找这种模式,但没有找到。在其他语言中这是非常常见的,但在Go语言中不太常见。

不过,你可能会发现这个链接有用:https://github.com/open-zhy/fn-pipe

它基本上使用反射来通过函数映射所有的输入和输出。

英文:

I was seeking for this kind of pattern as well without any luck. It's very common to other language but not in golang

Anyway, you may find this usefull https://github.com/open-zhy/fn-pipe

It basically uses reflection in order to map all your inputs and outputs through your functions

答案2

得分: 0

我也不太确定你想做什么,但是这是一个Go语言中链表实现的示例。

package main

import "fmt"

type LinkedList struct {
    value interface{}
    next  *LinkedList
}

func (oldNode *LinkedList) prepend(value interface{}) *LinkedList {
    return &LinkedList{value, oldNode}
}

func tail(value interface{}) *LinkedList {
    return &LinkedList{value, nil}
}

func traverse(ll *LinkedList) {
    if ll == nil {
        return
    }
    fmt.Println(ll.value)
    traverse(ll.next)
}

func main() {
    node := tail(5).prepend(6).prepend(7)
    traverse(node)
}

如你所见,可以使用所谓的"流畅"或"构建器"接口来链接方法。我认为上面的示例是一个适当的地方。如果你想要进行异步/非阻塞请求,我会使用通道/协程。虽然它不是真正的Promise,但你可以在成功/错误时进行处理。

func NonBlockingGet(url string) <-chan []byte {
    c := make(chan []byte, 1)

    go func() {
        var body []byte
        defer func() {
            c <- body
        }()

        res, err := http.Get(url)
        if err != nil {
            return
        }
        defer res.Body.Close()

        body, _ = ioutil.ReadAll(res.Body)
    }()

    return c
}

func main() {
    promise := NonBlockingGet("http://example.com")

    // 可以在这里做其他事情,因为是非阻塞的获取请求。
    log.Println("这将在响应长度之前输出")

    body := <-promise // 将在此处等待直到promise被解析。
    log.Printf("响应长度:%d", len(body))
}

希望这可以帮到你。正如上面的评论所说,这不是JavaScript,我们不应该试图模仿它。但是,你可以将<-promise分配给body,或者将<-promise作为参数传递给一个函数。

英文:

I am also not exactly sure what you want to do, however here is an example of a linked list implementation in Go.

package main

import &quot;fmt&quot;

type LinkedList struct {
	value interface{}
	next  *LinkedList
}

func (oldNode *LinkedList) prepend(value interface{}) *LinkedList {
	return &amp;LinkedList{value, oldNode}
}

func tail(value interface{}) *LinkedList {
	return &amp;LinkedList{value, nil}
}

func traverse(ll *LinkedList) {
	if ll == nil {
		return
	}
	fmt.Println(ll.value)
	traverse(ll.next)
}

func main() {
	node := tail(5).prepend(6).prepend(7)
	traverse(node)
}

So, as you can see, it is possible to chain methods using what is known as the fluent or builder interface. IMO above example is an appropriate place to do so. https://www.martinfowler.com/bliki/FluentInterface.html

Now if you want to do an async / non blocking request, then I would use channels / goroutines. It's not really a promise, but you can certainly handle on success/error if you wanted.

func NonBlockingGet(url string) &lt;-chan []byte {
    c := make(chan []byte, 1)

    go func() {
        var body []byte
        defer func() {
            c &lt;- body
        }()

        res, err := http.Get(url)
        if err != nil {
            return
        }
        defer res.Body.Close()

        body, _ = ioutil.ReadAll(res.Body)
    }()

    return c
}

func main() {
    promise := NonBlockingGet(&quot;http://example.com&quot;)

    // can do other stuff here - because doing a non-blocking get request.
    log.Println(&quot;This will output before the response length&quot;)

    body := &lt;- promise // Will wait here till promise is resolved.
    log.Printf(&quot;response length: %d&quot;, len(body))
}

I hope that this helps. As said in comments above, this is not javascript and we shouldnt try to be. However, instead of assigning &lt;- promise to body, you could always pass &lt;- promise as an argument into a function.

huangapple
  • 本文由 发表于 2017年3月16日 01:52:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/42817191.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定