英文:
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 "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)
}
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) <-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")
// can do other stuff here - because doing a non-blocking get request.
log.Println("This will output before the response length")
body := <- promise // Will wait here till promise is resolved.
log.Printf("response length: %d", 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 <- promise
to body
, you could always pass <- promise
as an argument into a function.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论