Home > Software engineering >  how to send any function through a channel in golang?
how to send any function through a channel in golang?

Time:11-29

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?

CodePudding user response:

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.

CodePudding user response:

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

https://go.dev/play/p/5b6VPfV45qo

  •  Tags:  
  • go
  • Related