3

I want to define a function to run a callback function, and the callback function will be uncertain, such as args or returns both are uncertain.

I try this:

package main

import (
    "fmt"
)

func F(callback func(args ...interface{}) interface{}, args ...interface{}) {
    rev := callback(args...)
    fmt.Println(rev)
}

func CB1() {
    fmt.Println("CB1 called")
}

func CB2() bool {
    fmt.Println("CB2 called")
    return false
}

func CB3(s string) {
    fmt.Println("CB3 called")
}

func CB4(s string) bool {
    fmt.Println("CB4 called")
    return false
}

func main() {
    F(CB1)
    F(CB2)
    F(CB3, "xxx")
    F(CB4, "yyy")
}

errors:

./play.go:31:3: cannot use CB1 (type func()) as type func(...interface {}) interface {} in argument to F
./play.go:32:3: cannot use CB2 (type func() bool) as type func(...interface {}) interface {} in argument to F
./play.go:33:3: cannot use CB3 (type func(string)) as type func(...interface {}) interface {} in argument to F
./play.go:34:3: cannot use CB4 (type func(string) bool) as type func(...interface {}) interface {} in argument to F
1
  • This feels like an XY problem. Is there an underlying problem we can help you solve in a more idiomatic Go way? Commented Oct 11, 2018 at 19:52

1 Answer 1

8

You can, but since Go does not support generics, you have to define callback to be of type interface{}.

To call a function value stored in callback, you may use reflection, namely the Value.Call() method.

This is how it would look like:

func F(callback interface{}, args ...interface{}) {
    v := reflect.ValueOf(callback)
    if v.Kind() != reflect.Func {
        panic("not a function")
    }
    vargs := make([]reflect.Value, len(args))
    for i, arg := range args {
        vargs[i] = reflect.ValueOf(arg)
    }

    vrets := v.Call(vargs)

    fmt.Print("\tReturn values: ")
    for _, vret := range vrets {
        fmt.Print(vret)
    }
    fmt.Println()
}

With this, the output of your app will be (try it on the Go Playground):

CB1 called
    Return values: 
CB2 called
    Return values: false
CB3 called
    Return values: 
CB4 called
    Return values: false
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.