英文:
how to send any function through a channel in golang?
问题
我可以帮你翻译代码部分,以下是翻译好的内容:
我想要实现一个类似下面的执行器:
type task func()
type executor struct {
tasks chan task
}
func (e *executor) Push(t task) {
select {
case e.tasks <- t:
default:
return
}
}
func (e *executor) Run() {
for {
select {
case t := <-e.tasks:
t()
}
}
}
func (e *executor) Init() {
e.tasks = make(chan task, 10)
}
然后,我想要将任何函数包装成task
类型,就像这个伪代码所示:
func make_task(f function_addr, args ...interface{}) task {
return func() {
f(args...)
}
}
我该如何实现这个功能?
英文:
I want to implement an executor like below:
type task func()
type executor struct {
tasks chan task
}
func (e *executor) Push(t task) {
select {
case e.tasks <- t:
default:
return
}
}
func (e *executor) Run() {
for {
select {
case t := <-e.tasks:
t()
}
}
}
func (e *executor) Init() {
e.tasks = make(chan task, 10)
}
Then, I want to wrap any function into task type, like this pseudo code:
func make_task(f function_addr, args ...interface{}) task{
return func(){
f(args...)
}
}
How can I achieve this?
答案1
得分: 1
你无法编写一个通用函数来实现你想要的功能,但是你可以使用闭包来实现你需要的功能,例如:
executor.Push(func() {
someFunc(arg1,arg2,...)
})
其中 arg1
、arg2
等是在代码中的那一点可用的参数。
英文:
You can't write a generic function to do what you want, but you can do what you need using closures like:
executor.Push(func() {
someFunc(arg1,arg2,...)
})
where arg1
, arg2
, etc. are arguments available at that point in code.
答案2
得分: 0
简单的方法是在make_task的位置使用一个函数字面量:
t := func() { exampleFunction(exampleArg1, exampleArg2) }
e.Push(t)
如果由于某种原因简单的方法不适用于你的应用程序,那么可以使用reflect包来调用任意函数并传递任意参数:
func make_task(f interface{}, args ...interface{}) task {
return func() {
values := make([]reflect.Value, len(args))
for i := range args {
values[i] = reflect.ValueOf(args[i])
}
reflect.ValueOf(f).Call(values)
}
}
示例:
func hello(arg string) {
fmt.Println("Hello", arg)
}
...
t := make_task(hello, "world")
t() // 输出 Hello world
点击此处查看示例代码。
英文:
The simple approach is to use a function literal in place of make_task:
t := func() { exampleFunction(exampleArg1, exampleArg2) }
e.Push(t)
If the simple approach does not fit into your application for some reason, then use the reflect package to call an arbitrary function with arbitrary arguments:
func make_task(f interface{}, args ...interface{}) task {
return func() {
values := make([]reflect.Value, len(args))
for i := range args {
values[i] = reflect.ValueOf(args[i])
}
reflect.ValueOf(f).Call(values)
}
}
Example:
func hello(arg string) {
fmt.Println("Hello", arg)
}
…
t := make_task(hello, "world")
t() // prints Hello world
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论